码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1493: [NOI2007]项链工厂(线段树)

时间:2016-02-16 09:55:03      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:

 

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\n",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\n",ans);
135         }
136     }
137     return 0;
138 }

 

bzoj 1493: [NOI2007]项链工厂(线段树)

标签:

原文地址:http://www.cnblogs.com/lidaxin/p/5191671.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!