您的位置:首页 > 其它

第五周训练总结(一)

2017-09-28 20:38 232 查看
第十六题:

 题目大意:一个长度为L的区间,最多有T种颜色,并且有O种操作,接下去有o行。一共就两种操作:1、C
a b c:表示的是将【a,b】这个区间染成颜色c。 2、P a b :表示的是询问【a,b】这个区间有多少种颜色。

思路:

这个题目做了两天才有了眉目,线段树区间更新,维护一个区间的颜色种类数就行了,由于只有30种颜色,可以考虑位操作,用一个int来表示。

这个题目需要注意的是不能一直更新到最下面,就更新到符合的区间即可,否则会超时。

买票的问题:

题目大意:

给定每个人插队时的位置及他们的号码,然后判断他们最终的位置。

解题思路:

由于最后插入的人的位置一定是固定的,(因为后面不会再有人把他向后挤),所以将这个人位置排好后,在确定下一个人的位置前把这个已排好的位置“丢掉”。这样对于插入到第i个位置,即搜索第i+1个空位。
#include <stdio.h>  

int p[200005];  

int v[200005];  

int ans[200005];  

struct Node

{  

    int l,r,num;  

}tree[1000000];    

void Build(int n,int x,int y)

{  

    tree
.l = x;  

    tree
.r = y;  

    tree
.num = (y - x + 1);

    int mid = (x + y) / 2;  

    if(x == y){  

        return;  

    }  

    Build(2*n,x,mid);  

    Build(2*n+1,mid+1,y);  

}  

  

void Modify(int n,int p,int v)

{  

    int l = tree
.l;  

    int r = tree
.r;  

    int mid = (l + r) / 2;  

    if(l == r){  

        tree
.num = 0;  

        ans[l] = v;  

        return;  

    }  

    if(tree[2*n].num >= p)  

    Modify(2*n,p,v);  

    else                    

    Modify(2*n+1,p - tree[2*n].num,v);  

    tree
.num = tree[2*n].num + tree[2*n+1].num;  

}  

  

int main()

{  

    int n;  

    int i;  

  

    while(scanf("%d",&n) != EOF)

{  

        Build(1,1,n);  

        for(i = 0;i < n;i++){  

            scanf("%d%d",&p[i],&v[i]);  

        }  

        for(i = n - 1;i >= 0;i--){  

            Modify(1,p[i]+1,v[i]);  

        }  

        for(i = 1;i < n;i++){  

            printf("%d ",ans[i]);  

        }  

        printf("%d\n",ans
);  

    }  

  

    return 0;  

}  

感觉这周的状态好了一些,没啥乱七八糟的事,能静下心来看题。还是做的很慢,自己还是要抓紧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: