Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 144 Accepted Submission(s): 72
Problem Description
Yellowstar is writing an article that contains N words and 1 picture, and the i-th word contains
Input
The first line of the input gives the number of test cases T; T test cases follow.
Each case begins with one line with four integers N, W, pw, dw : the number of words, page width, picture width and left margin.
The next line contains N integers w
Each case begins with one line with four integers N, W, pw, dw : the number of words, page width, picture width and left margin.
The next line contains N integers w
Output
For each query, output one integer denotes the minimum number of rows.
Sample Input
2
2 7 4 3
1 3
3
1 2
2 2
5 2
3 8 2 3
1 1 3
1
1 1
Sample Output
2
3
3
1
【题意】一张纸上写了些单词,每个单词处于同一行,不被分开,且两个单词之间有一个空格或换行。现在要在照片中 插入一张宽度固定的图片。Q次询问,问你当照片插进单词中,单词总共占据多少行。
【分析】先对于三种宽度w,dw,w-dw-pw,预处理 当第i个单词放在当前宽度最左端时,下一行第一个单词是哪个,h[i]表示第i个单词放在首端时剩下的需要占据多少行。然后倍增,s[i][j]表示在没有图片区域第i个单词放在最左端时,往下2^j行的第一个单词是哪个,然后t数组表示插入单词的区域。
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define met(a,b) memset(a,b,sizeof a) #define pb push_back #define mp make_pair #define rep(i,l,r) for(int i=(l);i<=(r);++i) #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int N = 1e5+5;; const int M = 17; const int mod = 1e9+7; const int mo=123; const double pi= acos(-1.0); typedef pair<int,int>pii; int n,w,q,pw,dw; int a[N],lto[N],rto[N]; int h[N],s[N][M],t[N][M]; void solve(int len,int to[]){ for(int i=0,j=0,x=-1;i<=n;i++){ while(x+a[j]+1<=len)x+=a[j++]+1; to[i]=j;x-=a[i]+1; } } int main() { int T; scanf("%d",&T); while(T--){ scanf("%d%d%d%d",&n,&w,&pw,&dw); rep(i,0,n-1)scanf("%d",&a[i]); a[n]=w+5; solve(w,lto); rep(i,0,n)s[i][0]=lto[i]; rep(j,1,M-1)rep(i,0,n)s[i][j]=s[s[i][j-1]][j-1]; h[n]=0; for(int i=n-1;i>=0;i--)h[i]=h[lto[i]]+1; solve(dw,lto);solve(w-dw-pw,rto); rep(i,0,n)t[i][0]=rto[lto[i]]; rep(j,1,M-1)rep(i,0,n)t[i][j]=t[t[i][j-1]][j-1]; scanf("%d",&q); while(q--){ int x,hh,res=0; scanf("%d%d",&x,&hh); int ans=0; ans+=min(--x,h[0]); rep(j,0,M-1)if(x>>j & 1)res=s[res][j]; rep(j,0,M-1)if(hh>>j & 1)res=t[res][j]; ans+=hh+h[res]; printf("%d\n",ans); } } return 0; }