[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]," 
"[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]," 
"[i==n]);
32     }
33     return 0;
34 }
原文地址:https://www.cnblogs.com/skylee03/p/8177136.html