zoukankan      html  css  js  c++  java
  • BZOJ1493 NOI2007 项链工厂 线段树模拟

    提交地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1493

    题目大意:给一个数列,进行一系列操作。包括旋转,翻转,改变等操作,以及查询颜色段数。

    题目分析:数列中元素的相对位置没有改变,因此不需要用splay去做,而是可以用线段树解决这类问题。

    旋转操作直接改变变量rotate,翻转操作用异或即可。每次询问先利用rotate求出当前1号位是谁,这样可以根据翻转标记确定区间。如果区间跨越n,那么合并的时候要考虑左边一段的右端和右边一段的左端。相同的时候答案要减少1.

     对于swap操作,由于是单点的,可以暴力在树上做。

    这题以我的代码水平来说比较难打。

    代码如下:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<algorithm>
      6 using namespace std;
      7 
      8 const int maxn = 600010;
      9 struct node{
     10     int lazy;
     11     int lft,rgt,tot,full;
     12 }t[maxn<<2];
     13 int n,c;
     14 int x[maxn];
     15 int fz,rt; // fanzhuan rotate
     16 int tl,tr;
     17 
     18 void push_down(int now){
     19     t[now<<1].lazy = t[now<<1|1].lazy = t[now].lazy;
     20     t[now].lft = t[now].rgt = t[now].lazy; t[now].tot = 1;
     21     t[now].lazy = 0;t[now].full = 1;
     22 }
     23 
     24 void push_up(int now){
     25     int L=(now<<1),R = L+1;
     26     if(t[now].lazy)push_down(now);
     27     if(t[L].lazy)push_down(L); if(t[R].lazy) push_down(R);
     28     t[now].lft = t[L].lft; t[now].rgt = t[R].rgt;
     29     t[now].tot = t[L].tot + t[R].tot;
     30     if(t[L].rgt == t[R].lft) t[now].tot--;
     31     if(t[L].full && t[R].full && t[L].rgt == t[R].rgt) t[now].full=1;
     32     else t[now].full = 0;
     33 }
     34 
     35 void build_tree(int l,int r,int now){
     36     if(l == r){
     37     t[now].lazy = 0; t[now].lft = x[l]; t[now].rgt = x[l];
     38     t[now].tot = 1;t[now].full = 1;
     39     }else{
     40     int mid = (l+r>>1);int L=(now<<1),R = L+1;
     41     build_tree(l,mid,L); build_tree(mid+1,r,R);
     42     push_up(now);
     43     }
     44 }
     45 
     46 void read(){
     47     scanf("%d%d",&n,&c);
     48     for(int i=1;i<=n;i++){
     49     scanf("%d",&x[i]);
     50     }
     51     build_tree(1,n,1);
     52 }
     53 
     54 void Rotate(){
     55     int now; scanf("%d",&now);
     56     if(fz == 1) rt += (n-now);
     57     else rt += now;
     58     rt %= n;
     59 }
     60 
     61 int get_ans(int l,int r,int now){
     62     if(now == 1) tl = 1,tr = n;
     63     if(t[now].lazy) push_down(now);
     64     if(tl > r || tr < l) return 0;
     65     if(tl >= l && tr <= r) return t[now].tot;
     66     int mid = (tl+tr) / 2;
     67     int ans = 0;
     68     int tmp = tr; tr=mid;
     69     int nnow = get_ans(l,r,now<<1);
     70     ans += nnow;
     71     tr = tmp;tmp = tl; tl = mid+1;
     72     int know = get_ans(l,r,now<<1|1);
     73     ans += know;
     74     tl = tmp;
     75     if(tr-tl!=0&&t[now<<1].rgt == t[now<<1|1].lft&&nnow&&know) ans--;
     76     push_up(now);
     77     return ans;
     78 }
     79 
     80 int get_color(int ord,int now){
     81     if(now == 1) tl = 1,tr = n;
     82     if(t[now].lazy) {push_down(now);return t[now].lft;}
     83     if(tl == tr) return t[now].lft;
     84     int mid = (tl+tr)/2;
     85     int ans;
     86     if(mid >= ord){tr = mid; ans = get_color(ord,now<<1);}
     87     else {tl = mid+1; ans = get_color(ord,now<<1|1);}
     88     push_up(now);
     89     return ans;
     90 }
     91 
     92 void Tpaint(int l,int r,int now,int xc){
     93     if(now == 1) tl = 1,tr = n;
     94     if(t[now].lazy) {push_down(now);}
     95     if(tl > r || tr < l) return;
     96     if(tl >= l && tr <= r) {t[now].lazy = xc;push_down(now);return;}
     97     int mid = (tl+tr)/2;
     98     int tmp = tr;tr = mid;
     99     Tpaint(l,r,now<<1,xc);
    100     tr = tmp; tmp = tl; tl = mid+1;
    101     Tpaint(l,r,now<<1|1,xc);
    102     tl = tmp;
    103     push_up(now);
    104 }
    105 
    106 int cnt;
    107 void Count(){
    108     int l,r,flag=0,flag2=0;
    109     char ch = getchar();
    110     cnt++;
    111     if(ch != 'S') {
    112     l = 1,r=n;
    113     int ans = t[1].tot-(t[1].lft == t[1].rgt && t[1].full==0);
    114     printf("%d
    ",ans);
    115     return;
    116     }else {
    117     scanf("%d%d",&l,&r);
    118     }
    119     int st = (1-rt); if(st <= 0) st += n;
    120     if(fz == 1){
    121     l = st-l+1; r = st-r+1;
    122     if(l <= 0) l += n; if(r <= 0) r += n;
    123     int ans = 0;
    124     if(l < r){
    125         ans += get_ans(1,l,1);
    126         ans += get_ans(r,n,1);
    127         if(t[1].lft == t[1].rgt) ans--;
    128     }else ans += get_ans(r,l,1);
    129     printf("%d
    ",ans);
    130     }else{
    131     l = st+l-1; r = st+r-1;
    132     if(l > n) l -= n; if(r > n) r -= n;
    133     int ans = 0;
    134     if(l > r){
    135         ans += get_ans(1,r,1);
    136         ans += get_ans(l,n,1);
    137         if(t[1].lft == t[1].rgt) ans--;
    138     }else ans += get_ans(l,r,1);
    139     printf("%d
    ",ans);
    140     }
    141 }
    142 
    143 void Paint(){
    144     int l,r,xc; scanf("%d%d%d",&l,&r,&xc);
    145     int st = (1-rt); if(st <= 0) st += n;
    146     if(fz == 1){
    147     l = st-l+1; r = st-r+1;
    148     if(l <= 0) l += n; if(r <= 0) r += n;
    149     if(l < r){ Tpaint(1,l,1,xc); Tpaint(r,n,1,xc);}
    150     else Tpaint(r,l,1,xc);
    151     }else{
    152     l = st+l-1; r = st+r-1;
    153     if(l > n) l -= n; if(r > n) r -= n;
    154     if(l > r){ Tpaint(1,r,1,xc); Tpaint(l,n,1,xc);}
    155     else Tpaint(l,r,1,xc);
    156     }
    157 }
    158 
    159 void Swap(){
    160     int l,r; scanf("%d%d",&l,&r);
    161     int st = (1-rt); if(st <= 0) st += n;
    162     if(fz == 1){
    163     l = st-l+1; r = st-r+1;
    164     if(l <= 0) l += n; if(r <= 0) r+= n;
    165     }else{
    166     l = st+l-1; r = st+r-1;
    167     if(l > n) l -= n; if(r > n) r -= n;
    168     }
    169     int nowl = get_color(l,1),nowr = get_color(r,1);
    170     Tpaint(l,l,1,nowr); Tpaint(r,r,1,nowl);
    171 }
    172 
    173 void work(){
    174     int q; scanf("%d",&q);
    175     for(int i=1;i<=q;i++){
    176     char ch = getchar();
    177     while(ch > 'Z' || ch < 'A')ch = getchar();
    178     switch(ch){
    179     case 'R':{Rotate();break;}
    180     case 'F':{fz ^= 1;break;}
    181     case 'S':{Swap();break;}
    182     case 'P':{Paint();break;}
    183     case 'C':{Count();break;}
    184     }
    185     }
    186 }
    187 
    188 int main(){
    189     //freopen("1.in","r",stdin);
    190     //freopen("1.out","w",stdout);
    191     read();
    192     work();
    193     return 0;
    194 }
  • 相关阅读:
    关于 " +new Date " 的个人见解
    利用text插件和css插件优化web应用
    gulp如何自定义插件
    NGINX实现域名跳转
    转:分享两个饼状图在线生成工具
    Windows下根据端口号查找进程并关闭【转载】
    树和二叉树
    学习表——受任于败军之际,奉命于危难之间(2.20--2.26)
    Incremental Method
    374. Guess Number Higher or Lower 简单的二分法运用
  • 原文地址:https://www.cnblogs.com/1-1-1-1/p/7846836.html
Copyright © 2011-2022 走看看