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
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;
}

 

相关文章: