TJOI2018 prepare

明天就是TJOI2018了,期待已久。

下午三点时候我告诉自己,做完TJOI2017不勤劳的图书管理员,就休息了。然后我就写+改到了现在。


先说题解吧。分块处理的,我也不会树套树,总之就是各种暴力。每一个整块都可以lower_bound+排序前缀和,直接求出贡献。零碎的部分枚举就可以,复杂度应该也是没问题的,并不是卡常或者数据弱。

#include <cstdio>
#include <cstring>
#include <cmath>
#define rint register int
#define N 50010
#include <algorithm>
typedef long long ll;
using namespace std;
const ll mo = 1e9 + 7;
inline char gc() {
	static char now[1<<16], *S, *T;
	if(S == T) {T = (S = now) + fread(now, 1, 1<<16, stdin); if(S == T) return EOF;}
	return *S++;
}
inline int read() {
	int x = 0, f = 1; char c = gc();
	while(c < '0' || c > '9') {if(c == '-') f = -1; c = gc();}
	while(c >= '0' && c <= '9') {x = x * 10 + c - 48; c = gc();}
	return x * f;
}
inline void print(int x) {
	if(x == 0) {puts("0"); return ;}
	if(x < 0) putchar('-'), x = 0 - x;
	int d[30], now = -1;
	while(x) {d[++now] = x % 10; x/= 10;}
	for(int i = now; i >= 0; --i) putchar('0' + d[i]); puts("");
}
int n, m, block, num;
int belong[N], q[N], mp[N]; ll s[500][200];
struct node {int x, y;}a[N], b[500];
inline void build(int x) {
	for(rint i = b[x].x; i <= b[x].y; ++i) q[i] = a[i].x;
	sort(q+b[x].x, q+b[x].y+1); for(rint i = 1; i <= b[x].y - b[x].x + 1; ++i) s[x][i] = 0;
	for(rint i = b[x].x; i <= b[x].y; ++i) s[x][i - b[x].x + 1] = (s[x][i - b[x].x] + mp[q[i]]) % mo;
}
ll bit1[N], ans = 0, bit2[N];
inline void add1(int x, ll v) {for(rint i = x; i <= n; i+= i & -i) bit1[i]+= v, bit1[i]%= mo;}
inline ll query1(int x) {ll ret = 0; for(rint i = x; i; i-= i & -i) ret+= bit1[i], ret%= mo; return ret;}
inline void add2(int x, ll v) {for(rint i = x; i <= n; i+= i & -i) bit2[i]+= v, bit2[i]%= mo;}
inline ll query2(int x) {ll ret = 0; for(rint i = x; i; i-= i & -i) ret+= bit2[i], ret%= mo; return ret;}
inline void init() {
	for(rint i = 1; i <= n; ++i) bit1[i] = bit2[i] = 0;
	for(rint i = n; i >= 1; --i) {
		ans+= query1(a[i].x - 1) + query2(a[i].x) * a[i].y; ans%= mo; if(ans < 0) ans+= mo;
		add1(a[i].x, a[i].y); add2(a[i].x, 1);
	}
}
int main() {
	n = read(); m = read();
	for(rint i = 1; i <= n; ++i) {a[i].x = read(); a[i].y = read(); mp[a[i].x] = a[i].y;}
	block = (int)sqrt(n)/2; num = 0;
	for(rint i = 1; i <= n; i+= block) {
		b[++num].x = i; b[num].y = min(n, i + block - 1);
		for(rint j = i; j <= b[num].y; ++j) belong[j] = num;
	}
	for(rint i = 1; i <= num; ++i) build(i); init();
	for(rint i = 1; i <= m; ++i) {
		int x = read(), y = read(); if(x > y) swap(x, y); if(x == y) {print(ans); continue;}
		int b1 = belong[x], b2 = belong[y];
		for(rint j = b1 + 1; j <= b2 - 1; ++j) {
			int sz = b[j].y - b[j].x + 1;
			int p1 = lower_bound(q+b[j].x, q+b[j].y+1, a[x].x) - q;
			p1-= b[j].x; ll temp1 = s[j][p1]; if(temp1 < 0) temp1+= mo;
			ll ctb1 = (p1 * a[x].y + temp1) % mo;
			int p2 = lower_bound(q+b[j].x, q+b[j].y+1, a[y].x) - q;
			p2-= b[j].x; ll temp2 = s[j][p2]; if(temp2 < 0) temp2+= mo;
			ll ctb2 = (p2 * a[y].y + temp2) % mo;
			ans+= ctb2 - ctb1; if(ans < 0) ans+= mo;
			ll temp = s[j][sz]; if(temp < 0) temp+= mo;
			ctb1 = ((sz - p1) * a[x].y + temp - temp1) % mo;
			ctb2 = ((sz - p2) * a[y].y + temp - temp2) % mo;
			ans+= ctb1 - ctb2; if(ans < 0) ans+= mo;
		}
		ll ad = 0;
		for(rint j = x + 1; j <= min(y - 1, b[b1].y); ++j) {
			if(a[x].x > a[j].x) ad-= a[x].y + a[j].y, ad%= mo; else ad+= a[x].y + a[j].y, ad%= mo; if(ad < 0) ad+= mo;
			if(a[y].x > a[j].x) ad+= a[y].y + a[j].y, ad%= mo; else ad-= a[y].y + a[j].y, ad%= mo; if(ad < 0) ad+= mo;
		}
		ll ad1 = ad;
		for(rint j = max(x + 1, b[b2].x); j <= y - 1; ++j) {
			if(a[j].x > a[y].x) ad-= a[y].y + a[j].y, ad%= mo; else ad+= a[y].y + a[j].y, ad%= mo; if(ad < 0) ad+= mo;
			if(a[j].x > a[x].x) ad+= a[x].y + a[j].y, ad%= mo; else ad-= a[x].y + a[j].y, ad%= mo; if(ad < 0) ad+= mo;
		}
		if(b1 == b2) ans+= ad1; else ans+= ad; ans%= mo;
		swap(a[x], a[y]); build(b1); build(b2);
		if(a[x].x < a[y].x) ans-= a[y].y + a[x].y; else ans+= a[y].y + a[x].y; if(ans < 0) ans+= mo; ans%= mo;
		print(ans);
	}
	return 0;
}

怎么说呢,从NOIP之后,到现在,虽然投入的不如学长们多,但也take up了我的大部分时间,以至于不交作业得罪了好多老师,尤其是可爱的cbin。我一般呢是不认怂的。但是反正他也不看blog【撇嘴】,在这给cbin等等可爱的老师们道个歉。

明天就考试了。虽然嘴上说无所谓,但其实还是挺在乎的。

学校杀......真是可怕啊

VisJiao,pickupwin,Richard_for_OI,注定只能有两个人出现在长沙。

两位大神们,这次我会全力以赴的,不求如何如何,只愿不留下遗憾。我想,全力以赴是对你们实力最好的尊重。

明天考场见。

最后祝我自己和所有明天参赛的小可爱们明天元气满满!!!

TJOI2018!Rua!Rua!Rua!

猜你喜欢

转载自blog.csdn.net/richard_for_oi/article/details/80138746