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 }
View Code

2016.3.9 update: 贴吧上有人分享了ZJOI2013 day1的课件+pdf题目+数据+题解,如果A掉但是BZOJ上过不了说明你被卡了……

http://tieba.baidu.com/p/2246816329

posted on 2016-03-08 22:01  ACMICPC  阅读(957)  评论(0编辑  收藏  举报

导航