BZOJ3110 [ZJOI2013] K大数查询(加强数据)
Posted ACMICPC
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3110 [ZJOI2013] K大数查询(加强数据)相关的知识,希望对你有一定的参考价值。
原来的题解:http://www.cnblogs.com/jimzeng/p/bzoj3110.html
有必要特意再写一篇题解……
OrzKPM!KPM加了两组数据结果我原来的代码就被叉了……
看到数据没有负数KPM就加了负数,然后还卡了long long(极端情况:50000次,每次在1,50000中加入一个同样的数)
需要离散化数据,加long long
然后速度就明显慢了……(9556ms -> 12292ms)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #define rep(i,l,r) for(int i=l; i<=r; i++) 6 #define clr(x,y) memset(x,y,sizeof(x)) 7 using namespace std; 8 typedef long long ll; 9 const int maxn = 50010; 10 inline int read(){ 11 int ans = 0, f = 1; 12 char c = getchar(); 13 for(; !isdigit(c); c = getchar()) 14 if (c == \'-\') f = -1; 15 for(; isdigit(c); c = getchar()) 16 ans = ans * 10 + c - \'0\'; 17 return ans * f; 18 } 19 struct Node{ 20 int ls,rs; int t; ll s; 21 }t[20000010]; 22 struct Function{ 23 int f,a,b,c; 24 }f[maxn]; 25 int n,m,N,sz = 0,cnt = 0,id[maxn],rt[maxn<<2]; 26 inline void pushdown(int w,int l,int r){ 27 if (!t[w].t || l == r) return; 28 if (!t[w].ls) t[w].ls = ++sz; 29 if (!t[w].rs) t[w].rs = ++sz; 30 t[t[w].ls].t += t[w].t; t[t[w].rs].t += t[w].t; 31 int mid = (l + r) >> 1; 32 t[t[w].ls].s += (mid - l + 1) * t[w].t; 33 t[t[w].rs].s += (r - mid) * t[w].t; 34 t[w].t = 0; 35 } 36 void modify(int u,int v,int &w,int l,int r){ 37 if (!w) w = ++sz; 38 pushdown(w,l,r); 39 if (u == l && v == r){ 40 t[w].s += (r - l + 1); 41 t[w].t++; return; 42 } 43 int mid = (l + r) >> 1; 44 if (v <= mid) modify(u,v,t[w].ls,l,mid); 45 else if (u > mid) modify(u,v,t[w].rs,mid+1,r); 46 else{ 47 modify(u,mid,t[w].ls,l,mid); 48 modify(mid+1,v,t[w].rs,mid+1,r); 49 } 50 t[w].s = t[t[w].ls].s + t[t[w].rs].s; 51 } 52 ll query(int u,int v,int w,int l,int r){ 53 if (!w) return 0; 54 pushdown(w,l,r); 55 if (u == l && v == r) return t[w].s; 56 int mid = (l + r) >> 1; 57 if (v <= mid) return query(u,v,t[w].ls,l,mid); 58 else if (u > mid) return query(u,v,t[w].rs,mid+1,r); 59 else return query(u,mid,t[w].ls,l,mid) + query(mid+1,v,t[w].rs,mid+1,r); 60 } 61 void insert(int a,int b,int c){ 62 int k = 1, l = 1, r = N; 63 while (l < r){ 64 int mid = (l + r) >> 1; 65 modify(a,b,rt[k],1,n); 66 if (c <= mid) r = mid, k <<= 1; 67 else l = mid + 1, k = k << 1 | 1; 68 } 69 modify(a,b,rt[k],1,n); 70 } 71 int solve(int a,int b,int c){ 72 int k = 1, l = 1, r = N; 73 while (l < r){ 74 int mid = (l + r) >> 1; 75 ll t = query(a,b,rt[k<<1],1,n); 76 if (t >= c) r = mid, k <<= 1; 77 else l = mid + 1, k = k << 1 | 1, c -= t; 78 } 79 return id[N - l + 1]; 80 } 81 int main(){ 82 n = read(); m = read(); 83 rep(i,1,m){ 84 f[i].f = read(), f[i].a = read(), f[i].b = read(), f[i].c = read(); 85 if (f[i].f == 1) id[++cnt] = f[i].c; 86 } 87 sort(id+1,id+cnt+1); 88 N = unique(id+1,id+cnt+1) - id - 1; 89 rep(i,1,m) if (f[i].f == 1) f[i].c = lower_bound(id+1,id+N+1,f[i].c) - id; 90 rep(i,1,m){ 91 if (f[i].f == 1){ 92 f[i].c = N - f[i].c + 1; insert(f[i].a,f[i].b,f[i].c); 93 } 94 else printf("%d\\n",solve(f[i].a,f[i].b,f[i].c)); 95 } 96 return 0; 97 }
2016.3.9 update: 贴吧上有人分享了ZJOI2013 day1的课件+pdf题目+数据+题解,如果A掉但是BZOJ上过不了说明你被卡了……
以上是关于BZOJ3110 [ZJOI2013] K大数查询(加强数据)的主要内容,如果未能解决你的问题,请参考以下文章