zoukankan      html  css  js  c++  java
  • bzoj 1493: [NOI2007]项链工厂(线段树)

    1493: [NOI2007]项链工厂

    Time Limit: 30 Sec  Memory Limit: 64 MB
    Submit: 1256  Solved: 545
    [Submit][Status][Discuss]

    Description

    Input

    输 入文件第一行包含两个整数N, c,分别表示项链包含的珠子数目以及颜色 数目。第二行包含N 个整数,x1, x2…, xn,表示从位置1 到位置N 的珠子的颜色, 1 ≤ xi ≤ c。第三行包含一个整数Q,表示命令数目。接下来的Q 行每行一条命令, 如上文所述。

    Output

    对于每一个C 和CS 命令,应输出一个整数代表相应的答案。

    Sample Input

    5 3
    1 2 3 2 1
    4
    C
    R 2
    P 5 5 2
    CS 4 1

    Sample Output

    4
    1

    HINT

    对于60%的数据,N ≤ 1 000,Q ≤ 1 000; 对于100%的数据,N ≤ 500 000,Q ≤ 500 000,c ≤ 1 000。

    【思路】

           线段树。

           R F之后虽然珠子的顺序变了,但是相对顺序是不变的。

           我们用MOV记录顺时针旋转量,F记录是否翻转。

           如果翻转则MOV-=k,否则MOV+=k。然后用MOV计算出查询位置对应的原位置,在原位置上进行操作。

           剩下的就是区间上的颜色修改以及统计颜色段数的问题了,可以用线段树完成。

           注意珠子是环形的,别忘比较一下1和n的颜色。

    【代码】

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
      6 using namespace std;
      7 
      8 const int N = 5*1e5+10;
      9 int n,m,c,MOV,F,co[N];
     10 //SEGMENT TREE
     11 struct Trie{ int l,r,s,c,lc,rc,setv; }T[N*4];
     12 void pushdown(int u) {
     13     if(T[u].l<T[u].r && T[u].setv!=-1) {
     14         int lc=u<<1,rc=lc|1;
     15         T[lc].c=T[rc].c=T[lc].setv=T[rc].setv=T[u].setv;
     16         T[lc].lc=T[lc].rc=T[rc].lc=T[rc].rc=T[u].setv;
     17         T[lc].s=T[rc].s=1;
     18         T[u].setv=-1;
     19     }
     20 }
     21 void maintain(int u) {
     22     int lc=u<<1,rc=lc|1;
     23     T[u].s=T[lc].s+T[rc].s-(T[lc].rc==T[rc].lc);
     24     T[u].lc=T[lc].lc,T[u].rc=T[rc].rc;
     25 }
     26 void build(int u,int L,int R) {
     27     T[u].l=L,T[u].r=R; T[u].setv=-1;
     28     if(L==R) {
     29         T[u].c=T[u].lc=T[u].rc=co[L]; T[u].s=1;
     30         return ;
     31     }
     32     int M=(L+R)>>1;
     33     build(u<<1,L,M) , build(u<<1|1,M+1,R);
     34     maintain(u);
     35 }
     36 void update(int u,int L,int R,int x) {
     37     pushdown(u);
     38     if(L<=T[u].l && T[u].r<=R) {
     39         T[u].setv=T[u].c=T[u].lc=T[u].rc=x;
     40         T[u].s=1;
     41     }
     42     else {
     43         int M=(T[u].l+T[u].r)>>1;
     44         if(L<=M) update(u<<1,L,R,x);
     45         if(M<R) update(u<<1|1,L,R,x);
     46         maintain(u);
     47     }
     48 }
     49 int query(int u,int L,int R)  {
     50     pushdown(u);
     51     if(L==T[u].l && T[u].r==R) {
     52         return T[u].s;
     53     }
     54     else {
     55         int M=(T[u].l+T[u].r)>>1;
     56         if(R<=M) return query(u<<1,L,R);
     57         else if(L>M) return query(u<<1|1,L,R);
     58         else {
     59             int ans=query(u<<1,L,M);
     60             ans+=query(u<<1|1,M+1,R);
     61             ans-=T[u<<1].rc==T[u<<1|1].lc;
     62             return ans;
     63         }
     64     }
     65 }
     66 int getcolor(int u,int x) {
     67     pushdown(u);
     68     if(T[u].l==T[u].r) return T[u].c;
     69     else {
     70         int M=(T[u].l+T[u].r)>>1;
     71         if(x<=M) return getcolor(u<<1,x);
     72         else return getcolor(u<<1|1,x);
     73     }
     74 }
     75 
     76 int get(int x) {
     77     if(F) x=n+2-x;
     78     x-=MOV;
     79     while(x<1) x+=n; 
     80     while(x>n) x-=n;
     81     return x;
     82 }
     83 void read(int& x) {
     84     char c=getchar(); x=0; int f=1;
     85     while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
     86     while(isdigit(c)) x=x*10+c-'0',c=getchar();
     87 }
     88 int main() {
     89     freopen("in.in","r",stdin);
     90     freopen("out.out","w",stdout);
     91     read(n),read(c);
     92     int x,a,b,c; char s[5];
     93     for(int i=1;i<=n;i++) read(co[i]);
     94     build(1,1,n);
     95     read(m);
     96     while(m--) {
     97         scanf("%s",s);
     98         if(s[0]=='R') {
     99             read(a);
    100             if(F) MOV-=a; else MOV+=a;
    101             while(MOV<0) MOV+=n;
    102             while(MOV>n) MOV-=n;
    103         } else
    104         if(s[0]=='F') F^=1; else 
    105         if(s[0]=='S') {
    106             read(a),read(b);
    107             a=get(a),b=get(b);
    108             int c1=getcolor(1,a),c2=getcolor(1,b);
    109             update(1,a,a,c2),update(1,b,b,c1);
    110         } else
    111         if(s[0]=='P') {
    112             read(a),read(b),read(c);
    113             a=get(a),b=get(b);
    114             if(F) swap(a,b);
    115             if(a>b) update(1,a,n,c),update(1,1,b,c);
    116             else update(1,a,b,c);
    117         } else
    118         if(s[0] && strlen(s)==1) {
    119             int ans=query(1,1,n);
    120             if(ans>1&&T[1].lc==T[1].rc) ans--;
    121             printf("%d
    ",ans);
    122         } else {
    123             read(a),read(b);
    124             a=get(a),b=get(b);
    125             if(F) swap(a,b);
    126             int ans;
    127             if(a<=b) {
    128                 ans=query(1,a,b);
    129                 if(a==1&&b==n&&ans>1&&T[1].lc==T[1].rc) ans--;
    130             } else {
    131                 ans=query(1,a,n)+query(1,1,b);
    132                 if(T[1].lc==T[1].rc) ans--;
    133             }
    134             printf("%d
    ",ans);
    135         }
    136     }
    137     return 0;
    138 }
  • 相关阅读:
    I/O中断处理详细过程
    移动端事件touchstart、touchmove、touchend
    页面刷新整理
    transform:rotate在手机上显示有锯齿的解决方案大全
    CSS3盒模型温故
    CSS3颜色特征温故
    CSS3文本温故
    CSS3背景温故
    怪诞咖啡的简介
    CSS3边框温故
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5191671.html
Copyright © 2011-2022 走看看