Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- const long long mod = 1e9 + 7;
- const double eps = 1e-15;
- const double PI = atan(1.0);
- #define readFile freopen("input","r",stdin)
- #define writeFile freopen("output","w",stdout)
- #define fastIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
- typedef pair<int,long long> ii;
- typedef unsigned long long ULL;
- const int N = 50003;
- const int inf = N-1;
- struct xorShift{
- private:
- ULL x,y,z,w;
- public:
- xorShift(){
- srand(time(NULL));
- }
- int next(){
- return rand();
- }
- };
- xorShift gen = xorShift();
- struct treap{
- int nxt,val;
- long long sz;
- ULL p;
- treap *l,*r;
- treap(){}
- treap(ii val){
- this->nxt = val.first;
- this->val = val.second;
- l = r = NULL;
- p = gen.next();
- }
- };
- #define pnode treap*
- inline long long sz(pnode node){
- return node?node->sz:0;
- }
- inline void usz(pnode node){
- if (node)
- node->sz = sz(node->l)+sz(node->r)+node->val;
- }
- void split(pnode node,pnode &l,pnode &r,int key){
- if (!node) l = r = NULL;
- else if (node->nxt<=key) split(node->r,node->r,r,key),l = node;
- else split(node->l,l,node->l,key),r = node;
- usz(node);
- }
- void merge(pnode &node,pnode l,pnode r){
- if (!l||!r) node = l?l:r;
- else if (l->p>r->p) merge(l->r,l->r,r),node = l;
- else merge(r->l,l,r->l),node = r;
- usz(node);
- }
- void tinsert(pnode &node,pnode &ins){
- if (!node) node = ins;
- else if (node->p<ins->p){
- split(node,ins->l,ins->r,ins->nxt);
- node = ins;
- }
- else tinsert(ins->nxt<=node->nxt?node->l:node->r,ins);
- usz(node);
- }
- inline bool eq(pnode node,ii val){
- return node->nxt == val.first && node->val == val.second;
- }
- void terase(pnode &node,ii val){
- if (!node) return;
- if (eq(node,val)){
- pnode temp = node;
- merge(node,node->l,node->r);
- free(temp);
- }
- else terase(val.first<=node->nxt?node->l:node->r,val);
- usz(node);
- }
- //long long tquery(pnode &node,int val){
- // pnode l; pnode r;
- // split(node,l,r,val);
- // long long res = sz(r);
- // merge(node,l,r);
- // return res;
- //}
- long long tquery(pnode node, int val){
- if (!node) return 0;
- if (node->nxt>val) return sz(node->r)+node->val+tquery(node->l,val);
- return tquery(node->r,val);
- }
- pnode tree[N*4];
- void insert(int node,int l,int r,int idx,ii val){
- pnode temp = new treap(val);
- tinsert(tree[node],temp);
- if (l==r) return;
- int mid = (l+r)>>1;
- if (idx<=mid) insert(node<<1,l,mid,idx,val);
- else insert(node<<1|1,mid+1,r,idx,val);
- }
- void update(int node,int l,int r,int idx,ii old,ii val){
- terase(tree[node],old);
- pnode temp = new treap(val);
- tinsert(tree[node],temp);
- if (l==r) return;
- int mid = (l+r)>>1;
- if (idx<=mid) update(node<<1,l,mid,idx,old,val);
- else update(node<<1|1,mid+1,r,idx,old,val);
- }
- long long query(int node,int l,int r,int ll,int rr){
- if (l>rr || r<ll) return 0;
- if (l>=ll && r<= rr) return tquery(tree[node],rr);
- int mid = (l+r)>>1;
- return query(node<<1,l,mid,ll,rr)+query(node<<1|1,mid+1,r,ll,rr);
- }
- int n,m,a,b;
- ii arr[N];
- int nxt[N],arr1[N];
- map<int,set<int> > dict;
- char c;
- #define sit set<int>::iterator
- inline void process1(int a){
- sit it = dict[arr1[a]].lower_bound(a);
- if (it!=dict[arr1[a]].begin()){
- it--;
- int idx = (*it);
- update(1,1,n,idx,make_pair(nxt[idx],arr1[idx]),make_pair(nxt[a],arr1[idx]));
- nxt[idx] = nxt[a];
- // insert(1,1,n,idx,make_pair(nxt[idx],arr1[idx]));
- }
- }
- inline void process(int a,int b){
- if (arr1[a]==b) return;
- process1(a);
- dict[arr1[a]].erase(a);
- dict[b].insert(a);
- sit it = dict[b].lower_bound(a);
- if (it!=dict[b].begin()){
- it--;
- int idx = (*it);
- int temp = nxt[idx];
- update(1,1,n,idx,make_pair(nxt[idx],b),make_pair(a,b));
- nxt[idx] = a;
- update(1,1,n,a,make_pair(nxt[a],arr1[a]),make_pair(temp,b));
- nxt[a] = temp;
- arr1[a] = b;
- return;
- }
- it++;
- if (it!=dict[b].end()){
- int idx = (*it);
- update(1,1,n,a,make_pair(nxt[a],arr1[a]),make_pair(idx,b));
- nxt[a] = idx;
- arr1[a] = b;
- return;
- }
- update(1,1,n,a,make_pair(nxt[a],arr1[a]),make_pair(inf,b));
- nxt[a] = inf;
- arr1[a] = b;
- }
- int main(){
- #ifndef ONLINE_JUDGE
- readFile;
- #endif
- // scanf("%d\n",&n);
- n = N-1;
- for(int i=1;i<=n;i++)
- arr[i].first = rand(),arr[i].second = i,dict[arr[i].first].insert(i),arr1[i]=arr[i].first;
- for(int i=0;i<N;i++) nxt[i] = inf;
- memset(tree,NULL,sizeof(tree));
- sort(arr+1,arr+n+1);
- for(int i=1;i<=n-1;i++){
- cout<<i<<"\n";
- if (arr[i].first==arr[i+1].first)
- nxt[arr[i].second] = arr[i+1].second;
- insert(1,1,n,arr[i].second,make_pair(nxt[arr[i].second],arr[i].first));
- }
- insert(1,1,n,arr[n].second,make_pair(nxt[arr[n].second],arr[n].first));
- scanf("%d",&m);
- while (m--){
- scanf("\n%c%d%d",&c,&a,&b);
- if (c=='Q') printf("%lld\n",query(1,1,n,a,b));
- else process(a,b);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement