题目链接

洛谷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\n",(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\n",(ans % P + P) % P);
}
return 0;
}

最新文章

  1. [Sass]嵌套
  2. 开发板tftp下载文件
  3. Java 8 Optional类深度解析
  4. 为sproto添加python绑定
  5. 常用jQuery代码01
  6. as(C# 参考)
  7. Tkinter教程之Message篇
  8. Javascript之相册拖动管理
  9. bat执行java程序的脚本解析
  10. Mysql笔记3数据库基本操作
  11. Swift 4 经典数据结构 Data Struct大全
  12. android面试题总结加强再加强版(一)
  13. 007_linux显示一个文件的某几行(中间几行)
  14. 微信小程序开发--第一个项目
  15. eclipse package视图和navigator视图的区别
  16. [Unity动画]05.Entry &amp; Exit &amp; Any State
  17. yii2.0 手动配置redis
  18. 奇怪吸引子---Bouali
  19. 转sklearn保存模型
  20. Linux - iptables firewalld

热门文章

  1. 「日常训练&amp;知识学习」莫队算法(二):树上莫队(Count on a tree II,SPOJ COT2)
  2. 「日常训练」 Counting Cliques(HDU-5952)
  3. python爬取视频网站m3u8视频,下载.ts后缀文件,合并成整视频
  4. Python 发邮件例子
  5. 数据库Mysql的学习(四)-表的记录操作
  6. vista x64 vs2010 win32添加资源 未能完成操作解决办法
  7. Redhat linux 安装SVN服务器 CollabNetSubversionEdge
  8. Python的实现分类
  9. 《剑指Offer》题三十一~题四十
  10. Qt单元测试(QTestLib)