UVA 12663 (线段树区间更新+二分查找,Q次区间更新后,求满足结果大于K的个数)
来源:互联网 发布:杭州市行知小学校地址 编辑:程序博客网 时间:2024/06/09 18:54
看见这种区间更新的题目,首先想到的就是线段树的区间更新。本体套用线段树的区间更新模板,更新的区间要二分去找。
#include<stdio.h>#include<string.h>#include<algorithm>#define MAX 200009#define LL long long intusing namespace std;LL a[MAX],cnt;struct Node { LL L; LL R; Node *pL; Node *pR; LL sum; LL add;} tree[4*MAX];LL n,m,k;LL ans;LL mid(struct Node *root) { return (root->L+root->R)/2;}LL Search(LL low,LL high,LL goal) { LL mid; while(low<=high){ mid=(low+high)/2; if(goal<=a[mid]){ high=mid-1; }else{ low=mid+1; } } return low;}void build(struct Node *root,LL L,LL R) { root->L=L; root->R=R; root->add=0; if(L==R) return; LL midd=(L+R)/2; cnt++; root->pL=tree+cnt; build(root->pL,L,midd); cnt++; root->pR=tree+cnt; build(root->pR,midd+1,R);}void add(struct Node *root, LL L, LL R, LL val) { if(root->L==L&&root->R==R) { root->add+=val; return; } LL midd=mid(root); if(R<=midd)add(root->pL, L, R, val); else if(L>midd) add(root->pR, L, R, val); else { add(root->pL, L, mid(root), val); add(root->pR, mid(root)+1, R,val); }}LL query(struct Node *root, LL L, LL R){ if(L == R){ if(root->add>=k) ans ++; return 0; } LL midd=mid(root); add(root->pL, root->L, midd, root->add); add(root->pR, midd+1, root->R, root->add); root->add=0; if(R<=midd) return query(root->pL, L, R); else if(L>midd) return query(root->pR, L, R); else return query(root->pL, L, midd)+query(root->pR, midd+1, R);}int main() { int t=1; while(~scanf("%lld %lld %lld",&n,&m,&k)) { cnt=0; ans=0; for(LL i=1; i<=n; i++) { scanf("%lld",&a[i]); } sort(a+1,a+n+1); build(tree,1,n); LL first=2,second; for(LL i=0; i<m; i++) { scanf("%lld",&second); LL firsttmp=lower_bound(a + 1, a + n + 1, first) - a; LL secondtmp = upper_bound(a + 1, a + n + 1, second) - a - 1; if(firsttmp>secondtmp) continue;// if(secondtmp>n) secondtmp=n; scanf("%lld",&first); if(secondtmp < firsttmp) continue; add(tree,firsttmp,secondtmp,1); first++; } query(tree,1,n); printf("Case %d: %lld\n",t++, ans); } return 0;}/*10 10 22 4 6 9 6 2 4 3 19 395 26 39 28 34 39 68 2Case 1: 69 8 23 7 2 9 8 4 3 2 15 26 39 28 49 210 646 510 3Case 2: 64 2 22 2 2 25 27 2Case 3: 0*/
还有一种方法,叫做差分,这适用于Q次更新,但是只有最后一次查询的状况,每次查询的时间复杂度是O(n).
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define MAX 100009#define inf 100000009int a[MAX],num[MAX],ans[MAX];int main(){ int n,m,k,t=1; while(~scanf("%d %d %d",&n,&m,&k)){ memset(num,0,sizeof(num)); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } sort(a+1,a+n+1); int first=2,second; for(int i=0;i<m;i++){ scanf("%d",&second); int firsttmp=lower_bound(a+1,a+n+1,first)-a; int secondtmp=upper_bound(a+1,a+1+n,second)-a-1; num[firsttmp]++; num[secondtmp+1]--; scanf("%d",&first); first++; } int cnt=0; ans[0]=0; for(int i=1;i<=n;i++){ ans[i]=ans[i-1]+num[i]; if(ans[i]>=k) cnt++; } printf("Case %d: %d\n",t++, cnt); }return 0;}
0 0
- UVA 12663 (线段树区间更新+二分查找,Q次区间更新后,求满足结果大于K的个数)
- ZOJ 3911 线段树 区间更新查找,求素数个数
- 求 区间[a,b]内满足p^k*q*^m(k>m)的数的个数
- 线段树的区间更新区间合并
- HDU6070(二分+线段树区间更新)
- 线段树的区间更新
- 线段树的区间更新
- 线段树更新区间查找点
- Uva 12299 线段树求区间最小值(RMQ) 区间查询单点更新
- UESTC 1425 求任意区间的LIS 线段树区间更新区间查询
- 线段树求区间和(单点更新)
- 线段树 单点更新求区间和
- hdu1556 线段树区间更新 求单点
- 线段树区间更新
- 线段树区间更新
- 线段树 区间更新
- 线段树区间更新
- 线段树-区间更新
- 火车站
- 睡眠和休眠:常见问题
- 数据结构之--不相交集
- (转) opencv_study|OpenCV 单通道三通道理解
- MySQL基础2---数据库的基本操作
- UVA 12663 (线段树区间更新+二分查找,Q次区间更新后,求满足结果大于K的个数)
- UVA 10887 - Concatenation of Languages
- hdu 4791 dp预处理+二分
- 安卓android中使用混淆proguard产生的bug
- 我地一篇文章
- wifi rtl8192cu
- linux虚拟内存管理
- voj1485 传球游戏 dp
- leetcode generate parentheses