HDU 6107 Typesetting 倍增

Typesetting

Problem Description

Yellowstar is writing an article that contains N words and 1 picture, and the i-th word contains ai characters.
The page width is fixed to W characters. In order to make the article look more beautiful, Yellowstar has made some rules:

1. The fixed width of the picture is pw. The distance from the left side of the page to the left side of the photo fixed to dw, in other words, the left margin is dw, and the right margin is W - pw - dw.
2. The photo and words can‘t overlap, but can exist in same line.
3. The relative order of words cannot be changed.
4. Individual words need to be placed in a line.
5. If two words are placed in a continuous position on the same line, then there is a space between them.
6. Minimize the number of rows occupied by the article according to the location and height of the image.

However, Yellowstar has not yet determined the location of the picture and the height of the picture, he would like to try Q different locations and different heights to get the best look. Yellowstar tries too many times, he wants to quickly know the number of rows each time, so he asked for your help. It should be noted that when a row contains characters or pictures, the line was considered to be occupied.

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 ai, indicates i-th word consists of ai characters.
The third line contains one integer Q. 
Then Q lines follow, each line contains the values of xi and hi, indicates the starting line and the image height of the image.

Limits
T≤10
1≤N,W,Q≤105
1≤pw,ai≤W
0≤dw≤W−pw

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

题意:

  给你n个单词,放到宽度是W的文档里,每个单词不能跨行,在一行的连续的单词必须有空格隔开

  现在,在第 xi 行 距离文档左边框 dw的位置 放一个 宽度pw ,长度hi 的 图片,现在把单词全部填上去,问最少占多少行(只要有单词或者图片都算被占)

题解:

  设定f[i][j],表示以 第 i 个单词 开始 给你 2^j行 能放到第几个单词

  pw, dw,w是给定的,所以我们对于所有询问,无非就是  三种 宽度, 我们用倍增预处理三种宽度的 f 数组就行了

  我写的挫,复杂度:O(Q*logn*logn + n*logn)

下面给出AC代码

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
typedef unsigned long long ULL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = 2e5+10, M = 1e3+20,inf = 2e9;

int f[N][25],n,w,pw,dw,a[N],g[N][25];
LL sum[N];
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d%d%d",&n,&w,&pw,&dw);
        for(int i = 1; i <= n; ++i) scanf("%d",&a[i]);
        memset(g,0,sizeof(g));
        memset(f,0,sizeof(f));
        sum[0] = 0;
        for(int i = 1; i <= n; ++i) sum[i] = sum[i-1] + 1LL*a[i] + 1LL;
        for(int i = 1; i <= n; ++i)
        {
            int l = i,r = n;
            while(l <= r) {
                int md = (l + r) >> 1;
                if(sum[md] - sum[i-1] - 1<= 1LL*w) f[i][0] = md,l = md+1;
                else r = md-1;
            }

            l = i,r = n;
            int now = -1;
            while(l <= r) {
                int md = (l + r) >> 1;
                if(sum[md] - sum[i-1] - 1 <= 1LL*dw) now = md,l = md+1;
                else r = md-1;
            }

            if(now == -1) g[i][0] = i-1;
            else g[i][0] = now;

            l = g[i][0] + 1,r = n,now = -1;
            while(l <= r) {
                int md = (l + r) >> 1;
                if(sum[md] - sum[g[i][0]] - 1 <= 1LL*(w - pw - dw)) now = md,l = md+1;
                else r = md-1;
            }
            if(now != -1) g[i][0] = now;
        }
        for(int j = 1; j <= 18; ++j)
              for(int i = 1; i <= n; ++i){
                if(f[i][j-1] == n) f[i][j] = n;
                else f[i][j] = f[f[i][j-1] + 1][j-1];
            }
          for(int j = 1; j <= 18; ++j)
              for(int i = 1; i <= n; ++i){
                if(g[i][j-1] == n) g[i][j] = n;
                else
                g[i][j] = g[g[i][j-1] + 1][j-1];
            }

        int Q;
        scanf("%d",&Q);
        while(Q--) {
            int x,h;
            scanf("%d%d",&x,&h);

            x -= 1;

            int now = 0,l,r,ans;
            for(int i = 18; i >= 0; --i)
                if(((x>>i)&1) && now != n)now = f[now+1][i];
            if(now == n) {
                l = 1; r = x,ans = 1;
                while(l <= r) {
                    int md = (l+r)>>1;
                    now = 0;
                    for(int i = 18; i >= 0; --i)
                        if(((md>>i)&1) && now != n)now = f[now+1][i];
                    if(now == n) ans = md,r = md-1;
                    else l = md+1;
                }
                printf("%d\n",ans + h);
                continue;
            }

            int tmp = now;
            for(int i = 20; i >= 0; --i)
                if(((h>>i)&1) && now != n) now = g[now+1][i];
            if(now == n) {
                printf("%d\n",h + x);
                continue;
            }
            tmp = now;
            l = 0; r = 100005,ans = 100005;
            while(l <= r) {
                int md = (l+r)>>1;
                now = tmp;
                for(int i = 18; i >= 0; --i)
                    if(((md>>i)&1) && now != n)now = f[now+1][i];
                if(now == n) ans = md,r = md-1;
                else l = md+1;
            }
            printf("%d\n",x + ans + h);
        }
    }
    return 0;
}

Typesetting

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 199    Accepted Submission(s): 95

Problem Description

Yellowstar is writing an article that contains N words and 1 picture, and the i-th word contains ai characters.
The page width is fixed to W characters. In order to make the article look more beautiful, Yellowstar has made some rules:

1. The fixed width of the picture is pw. The distance from the left side of the page to the left side of the photo fixed to dw, in other words, the left margin is dw, and the right margin is W - pw - dw.
2. The photo and words can‘t overlap, but can exist in same line.
3. The relative order of words cannot be changed.
4. Individual words need to be placed in a line.
5. If two words are placed in a continuous position on the same line, then there is a space between them.
6. Minimize the number of rows occupied by the article according to the location and height of the image.

However, Yellowstar has not yet determined the location of the picture and the height of the picture, he would like to try Q different locations and different heights to get the best look. Yellowstar tries too many times, he wants to quickly know the number of rows each time, so he asked for your help. It should be noted that when a row contains characters or pictures, the line was considered to be occupied.

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 ai, indicates i-th word consists of ai characters.
The third line contains one integer Q. 
Then Q lines follow, each line contains the values of xi and hi, indicates the starting line and the image height of the image.

Limits
T≤10
1≤N,W,Q≤105
1≤pw,ai≤W
0≤dw≤W−pw

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

Source

时间: 2024-10-23 11:18:07

HDU 6107 Typesetting 倍增的相关文章

HDU 6107 Typesetting (倍增)

Typesetting 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-

HDU 4547 LCA倍增算法

CD操作 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1111    Accepted Submission(s): 297 Problem Description 在Windows下我们可以通过cmd运行DOS的部分功能,其中CD是一条很有意思的命令,通过CD操作,我们可以改变当前目录. 这里我们简化一下问题,假设只有一个根目录,

H - Typesetting HDU - 6107

Yellowstar is writing an article that contains N words and 1 picture, and the i-th word contains aiaicharacters. The page width is fixed to W characters. In order to make the article look more beautiful, Yellowstar has made some rules: 1. The fixed w

hdu 5726 GCD 倍增+ 二分

题目链接 给n个数, 定义一个运算f[l,r] = gcd(al, al+1,....ar). 然后给你m个询问, 每次询问给出l, r. 求出f[l, r]的值以及有多少对l', r' 使得f[l, r] = f[l', r']. 第一个很简单, 用倍增的思想就可以了. 然后是第二个, 我们枚举每一个左端点i, 显然f[i, j]是只降不增的. 那么我们可以二分找到所有使得f[i, j]下降的值j. 因为gcd每次至少变为原来的二分之一, 而ai最大为1e9. 所以最多只有log2(1e9)个

HDU 4822 Tri-war(LCA树上倍增)(2013 Asia Regional Changchun)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4822 Problem Description Three countries, Red, Yellow, and Blue are in war. The map of battlefield is a tree, which means that there are N nodes and (N – 1) edges that connect all the nodes. Each country

HDU 5296 Annoying Problem 树链剖分 LCA 倍增法

HDU 5296 Annoying Problem 题目链接:hdu 5296 题意:在一棵给定的具有边权的树,一个节点的集合S(初始为空),给定Q个操作,每个操作增加或删除S中的一个点,每个操作之后输出使集合S中所有点联通的最小子树的边权和. 思路:最小子树上的节点的充要条件: 节点为(S集合中所有点的LCA)的子节点: 节点有一个子孙为S集合中的点. 那么我们给每个节点都开一个标记数组,初始为零,每加入一个节点,就把从这个节点到根节点路径上的点的值都+1,反之-1,这样通过对每个单节点值的查

HDU 5785 Function 【倍增】 (2016 ACM/ICPC Asia Regional Dalian Online)

Function Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 976    Accepted Submission(s): 375 Problem Description The shorter, the simpler. With this problem, you should be convinced of this tru

HDU 4081 Qin Shi Huang&#39;s National Road System 最小生成树+倍增求LCA

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081 Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5428    Accepted Submission(s): 1902 Problem Description

hdu 2586 How far away ?倍增LCA

hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增求取LCA,同时跟新距离数组 因为 \(2^{16} > 40000\) 所以所以表示祖先的数组dp[][]第二维取到16即可 就这道题来说,与比较tarjan比较,稍快一点 代码: #include <iostream> #include <algorithm> #includ