zoukankan      html  css  js  c++  java
  • 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】

    题目链接

    洛谷P3759

    题解

    树状数组套主席树板题

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cls(s) memset(s,0,sizeof(s))
    #define cp pair<int,int>
    #define LL long long int
    #define lbt(x) (x & -x)
    using namespace std;
    const int maxn = 100005,maxm = 10000005,INF = 1000000000,P = 1000000007;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    int sum[maxm],siz[maxm],ls[maxm],rs[maxm],cnt;
    void upd(int u){
    	sum[u] = (sum[ls[u]] + sum[rs[u]]) % P;
    	siz[u] = siz[ls[u]] + siz[rs[u]];
    }
    void Modify(int& u,int l,int r,int pos,int v,int vv){
    	if (!u) u = ++cnt;
    	if (l == r){sum[u] += v; siz[u] += vv; return;}
    	int mid = l + r >> 1;
    	if (mid >= pos) Modify(ls[u],l,mid,pos,v,vv);
    	else Modify(rs[u],mid + 1,r,pos,v,vv);
    	upd(u);
    }
    cp Query(int u,int l,int r,int L,int R){
    	if (!u) return mp(0,0);
    	if (l >= L && r <= R) return mp(sum[u],siz[u]);
    	int mid = l + r >> 1;
    	if (mid >= R) return Query(ls[u],l,mid,L,R);
    	if (mid < L) return Query(rs[u],mid + 1,r,L,R);
    	cp t = Query(ls[u],l,mid,L,R),tt = Query(rs[u],mid + 1,r,L,R);
    	return mp((t.first + tt.first) % P,t.second + tt.second);
    }
    int rt[maxn << 2],n,m,N = 100005,A[maxn],V[maxn]; LL ans;
    void modify(int u,int pos,int v,int vv){
    	for (int i = u; i <= N; i += lbt(i))
    		Modify(rt[i],1,N,pos,v,vv);
    }
    cp query(int l,int r,int L,int R){
    	if (L > R) return mp(0,0);
    	cp re = mp(0,0),t;
    	for (int i = r; i; i -= lbt(i)){
    		t = Query(rt[i],1,N,L,R);
    		re.first = (re.first + t.first) % P;
    		re.second += t.second;
    	}
    	for (int i = l - 1; i; i -= lbt(i)){
    		t = Query(rt[i],1,N,L,R);
    		re.first = (re.first - t.first + P) % P;
    		re.second -= t.second;
    	}
    	return re;
    }
    int main(){
    	n = read(); m = read();
    	int x,y; cp t,tt;
    	REP(i,n){
    		A[i] = read(); V[i] = read();
    		if (i - 1){
    			t = query(1,i - 1,A[i] + 1,N);
    			ans = ((ans + t.first) % P + 1ll * t.second * V[i] % P) % P;
    		}
    		modify(i,A[i],V[i],1);
    	}
    	while (m--){
    		x = read(); y = read();
    		if (x == y){printf("%lld
    ",(ans % P + P) % P); continue;}
    		if (x > y) swap(x,y);
    		if (A[x] < A[y]) ans = ((ans + V[x]) % P + V[y]) % P;
    		else ans = ((ans - (V[x] + V[y]) % P) % P + P) % P;
    		if (x < y){
    			t = query(x + 1,y - 1,A[x] + 1,N);
    			tt = query(x + 1,y - 1,1,A[x] - 1);
    			t.first = (t.first - tt.first) % P; t.second -= tt.second;
    			ans = ((ans + t.first) % P + 1ll * V[x] * t.second % P) % P;
    			t = query(x + 1,y - 1,1,A[y] - 1);
    			tt = query(x + 1,y - 1,A[y] + 1,N);
    			t.first = ((t.first - tt.first) % P + P) % P; t.second -= tt.second;
    			ans = ((ans + t.first) % P + 1ll * V[y] * t.second % P) % P;
    		}
    		modify(x,A[x],-V[x],-1);
    		modify(y,A[y],-V[y],-1);
    		modify(x,A[y],V[y],1);
    		modify(y,A[x],V[x],1);
    		swap(A[x],A[y]); swap(V[x],V[y]);
    		printf("%lld
    ",(ans % P + P) % P);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    Codeforces Round #657 (Div. 2) 题解
    洛谷 P2765 魔术球问题 (最小路径覆盖 or 贪心)
    洛谷 P2472 蜥蜴 (最大流)
    Codeforces Round #665 (Div. 2) 题解
    洛谷 P1231 教辅的组成 (三分图匹配,裂点)
    USACO5.4 奶牛的电信Telecowmunication (最小割,割边转割点)
    有关网络流的一些板子题
    洛谷 p2756 飞行员配对方案问题(最大流,二分图匹配)
    JSON.toJSONString中序列化空字符串遇到的坑
    关于mysql自动备份的小方法
  • 原文地址:https://www.cnblogs.com/Mychael/p/9108971.html
Copyright © 2011-2022 走看看