[CF911G]Mass Change Queries
题目大意:
给你一个长度为n的数列a,按顺序进行以下m次操作,每次将区间[l,r]中的所有x变成y,问最后数列是怎样的。
思路:
线段树。
每个线段树结点上维护当前区间每个数分别会变成多少。时间复杂度O(m log n)。然而比别人Ofast+循环展开+特定指令集的O(nm)暴力还慢。
1 #include<cstdio> 2 #include<cctype> 3 #include<algorithm> 4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x; 10 } 11 const int N=200001,A=101; 12 int a[N]; 13 class SegmentTree { 14 #define _left <<1 15 #define _right <<1|1 16 private: 17 int val[N<<2][A]; 18 void push_down(const int &p) { 19 for(register int i=1;i<A;i++) { 20 val[p _left][i]=val[p][val[p _left][i]]; 21 val[p _right][i]=val[p][val[p _right][i]]; 22 } 23 for(register int i=1;i<=A;i++) val[p][i]=i; 24 } 25 public: 26 void build(const int &p,const int &b,const int &e) { 27 for(register int i=1;i<A;i++) { 28 val[p][i]=i; 29 } 30 if(b==e) return; 31 const int mid=(b+e)>>1; 32 build(p _left,b,mid); 33 build(p _right,mid+1,e); 34 } 35 void modify(const int &p,const int &b,const int &e,const int &l,const int &r,const int &x,const int &y) { 36 if(b==l&&e==r) { 37 for(register int i=1;i<A;i++) { 38 if(val[p][i]==x) val[p][i]=y; 39 } 40 return; 41 } 42 push_down(p); 43 const int mid=(b+e)>>1; 44 if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),x,y); 45 if(r>mid) modify(p _right,mid+1,e,std::max(mid+1,l),r,x,y); 46 } 47 void stat(const int &p,const int &b,const int &e) { 48 if(b==e) { 49 a[b]=val[p][a[b]]; 50 return; 51 } 52 push_down(p); 53 const int mid=(b+e)>>1; 54 stat(p _left,b,mid); 55 stat(p _right,mid+1,e); 56 } 57 #undef _left 58 #undef _right 59 }; 60 SegmentTree t; 61 int main() { 62 const int n=getint(); 63 for(register int i=1;i<=n;i++) { 64 a[i]=getint(); 65 } 66 t.build(1,1,n); 67 for(register int q=getint();q;q--) { 68 const int l=getint(),r=getint(),x=getint(),y=getint(); 69 t.modify(1,1,n,l,r,x,y); 70 } 71 t.stat(1,1,n); 72 for(register int i=1;i<=n;i++) { 73 printf("%d%c",a[i]," \n"[i==n]); 74 } 75 return 0; 76 }
O(n^2)卡常版本:
1 #pragma GCC optimize("Ofast") 2 #pragma GCC optimize ("unroll-loops") 3 #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") 4 #include<cstdio> 5 inline char getint8() { 6 register char ch; 7 while(!__builtin_isdigit(ch=getchar())); 8 register char x=ch^'0'; 9 while(__builtin_isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return x; 11 } 12 inline int getint32() { 13 register char ch; 14 while(!__builtin_isdigit(ch=getchar())); 15 register int x=ch^'0'; 16 while(__builtin_isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 17 return x; 18 } 19 int n,m,l,r; 20 char x,y,a[200000]; 21 int main() { 22 n=getint32(); 23 for(register int i=0;i<n;i++) a[i]=getint8(); 24 for(register int m=getint32();m;m--) { 25 l=getint32(),r=getint32(),x=getint8(),y=getint8(); 26 for(l--;l<r;l++) { 27 if(__builtin_expect(a[l]==x,0)) a[l]=y; 28 } 29 } 30 for(register int i=0;i<n;i++) { 31 printf("%hhu%c",a[i]," \n"[i==n]); 32 } 33 return 0; 34 }