E. Goodbye souvenir time limit per test 6 seconds memory limit per test megabytes input standard input output standard Output
I won ' t feel lonely, nor would I be sorrowful ... not before everything is buried.
A string of n beads is left as the message of leaving. The beads is numbered from 1-to-N from left-to-right, and each has a shape numbered by integers between 1 and n inclusive. Some beads may have the same shapes.
The memory of a shape x in a certain subsegment of beads, was defined to being the difference between the last position and th E first position that shape X appears in the segment. The memory of a subsegment is the sum of memories through all shapes, that occur in it.
From time-to-time, shapes of beads change as well as the memories. Sometimes, the past secreted in subsegments is being recalled, and you is to find the memory for each of the them. Input
The first line of input contains-space-separated integers n and M (1≤n, m≤100)-the number of beads in the St Ring, and the total number of changes and queries, respectively.
The second line contains n integers a1, a2, ..., an (1≤ai≤n)-the initial shapes of beads 1, 2, ..., n, respectively.
The following m lines each describes either a change in the beads or a query of subsegment. A Line have one of the following formats:1 p X (1≤p≤n, 1≤x≤n), meaning that the shape of the p-th bead is changed into X; 2 L R (1≤l≤r≤n), denoting a query of memory of the subsegment from L to R, inclusive. Output
For each query, print one line with an integer-the memory of the recalled Subsegment. Examples input
7 6
1 2 3 1 3 2 1 2
3 7
2 1 3
1 7 2
1 3 2
2 1 6
2 5 7
Output
5
0
7
1
Input
7 5
1 3 2 1 4 2 3 1
1 4
2 2 3
1 1 7
2 4 5
1 1 7
Output
0
0
Note
The initial string of beads has shapes (1, 2, 3, 1, 3, 2, 1).
Consider the changes and queries in their Order:2 3 7:the memory of the subsegment [3, 7] is (7-4) + (6-6) + (5-3) = 5; 2 1 3:the Memory of the subsegment [1, 3] is (1-1) + (2-2) + (3-3) = 0; 1 7 2:the shape of the 7-th bead changes into 2. Beads now has shapes (1, 2, 3, 1, 3, 2, 2) respectively; 1 3 2:the shape of the 3-rd bead changes into 2. Beads now has shapes (1, 2, 2, 1, 3, 2, 2) respectively; 2 1 6:the Memory of the subsegment [1, 6] is (4-1) + (6-2) + (5-5) = 7; 2 5 7:the Memory of the subsegment [5, 7] is (7-6) + (5-5) = 1.
Maintenance of a data structure that supports two operations:
1. Single Point modification
2. For a given interval, query for a position minus the last occurrence of the current position number in the interval.
Since it is required that the current number of the last occurrence is also within the interval, each number can be reduced to the coordinate form: (x, Y)
X represents the current position, and Y indicates where the current value last occurred
For this point, we give the weight y-x.
Then a query can be regarded as the sum of weights in the matrix of l<=x<=r,l<=y<=r, the modification can be divided into: Remove the weight of the previous value effect, add the current value of the weight of the impact of two parts of the implementation, can be maintained by set.
It is obvious that two-dimensional line segments, two-dimensional tree arrays and so on can be used, but it is difficult to write. At this time can be on the CDQ divided treatment.
Each time the division of the time, in accordance with the x-coordinate sorting, maintain the subscript as the y-coordinate, the value of the weight of the tree array.
It is worth noting that the tree array needs to be zeroed after each partition.
Finally ran the 514MS,CF evaluation machine speed really fast.
#include <cstdio> #include <iostream> #include <string.h> #include <string> #include <map > #include <queue> #include <vector> #include <set> #include <algorithm> #include <math.h&
Gt #include <cmath> #include <stack> #define MEM0 (a) memset (A,0,sizeof (a)) #define Meminf (a) memset (a,0x3f,
sizeof (a)) #define N 100000 using namespace std;
typedef long Long LL;
typedef long double LD;
typedef double DB;
const int maxn=100005,inf=0x3f3f3f3f;
const LL LLINF=0X3F3F3F3F3F3F3F3F;
Const LD Pi=acos ( -1.0L);
int A[MAXN],T[MAXN];
ll ANS[MAXN],F[MAXN];
int num,qn;
Set<int> S[MAXN];
struct query {int type,pos,id,pre,val; BOOL operator< (const query &x) const {return Pos<x.pos | |
(Pos==x.pos&&type<x.type);
}
};
Query q[maxn*7],tem[maxn*7];
int lowbit (int x) {return x& (-X);}
ll getsum (int tt) {ll sum=0;
for (int t=tt;t;t-=lowbit (t)) sum+=f[t];
return sum; } void Update (int tt,ll c) {int t=tt;
for (int t=tt;t<=n;t+=lowbit (t)) f[t]+=c;
} void Cdq (int l,int r) {int mid= (L+R)/2;
if (l!=r) CDQ (L,mid), CDQ (MID+1,R);
int h=l,t=mid+1,cnt=0;
while (h<=mid&&t<=r) {if (Q[h]<q[t]) {if (q[h].type==1) update (Q[H].ID,Q[H].PRE);
Tem[cnt++]=q[h++];
} else {if (q[t].type==2) ans[q[t].val]-=getsum (q[t].pre)-getsum (q[t].id-1);
else if (q[t].type==3) ans[q[t].val]+=getsum (q[t].pre)-getsum (q[t].id-1);
Tem[cnt++]=q[t++];
}} int o=h;
for (; h<=mid;h++) tem[cnt++]=q[h];
for (; t<=r;t++) {if (q[t].type==2) ans[q[t].val]-=getsum (q[t].pre)-getsum (q[t].id-1);
else if (q[t].type==3) ans[q[t].val]+=getsum (q[t].pre)-getsum (q[t].id-1);
TEM[CNT++]=Q[T];
} for (int i=l;i<o;i++) if (q[i].type==1) update (Q[I].ID,-Q[I].PRE);
for (int i=0;i<cnt;i++) q[l+i]=tem[i];
} int main () {int n,m,i,x,y,z;
scanf ("%d%d", &n,&m);
MEM0 (t);
num=qn=0;
for (i=1;i<=n;i++) {scanf ("%d", &a[i]); S[a[i]].insert (i);
if (t[a[i]]!=0) q[++num]= (query) {1,i,t[a[i]],i-t[a[i]],0};
T[a[i]]=i;
} Set<int>::iterator it,j,k;
for (i=1;i<=m;i++) {scanf ("%d%d%d", &z,&x,&y);
if (z==1) {it=s[a[x]].find (x); j=k=it;k++;
if (It!=s[a[x]].begin ()) {j--;
q[++num]= (query) {1,x,*j,*j-x,0};
if (K!=s[a[x]].end ()) q[++num]= (query) {1,*k,*j,*k-*j,0};
} if (K!=s[a[x]].end ()) q[++num]= (query) {1,*k,x,x-*k,0};
S[a[x]].erase (IT);
S[y].insert (x);
A[x]=y;
J=k=it=s[y].find (x);
k++;
if (It!=s[y].begin ()) {j--;
q[++num]= (query) {1,x,*j,x-*j,0};
if (K!=s[y].end ()) q[++num]= (query) {1,*k,*j,*j-*k,0};
} if (K!=s[y].end ()) q[++num]= (query) {1,*k,x,*k-x,0};
} else {q[++num]= (query) {2,X-1,X,Y,++QN};
q[++num]= (query) {3,Y,X,Y,QN};
}} mem0 (ans); Mem0 (f);
/* for (i=1;i<=num;i++) {printf ("%d%d%d%d%d%d\n", i,q[i].type,q[i].pos,q[i].id,q[i].pre,q[i].val);
}*/CDQ (1,num);
for (i=1;i<=qn;i++) printf ("%i64d\n", Ans[i]); return 0;
}