hdu5517 二维线段树
来源:互联网 发布:nike跑步软件下载 编辑:程序博客网 时间:2024/06/06 02:33
题意:N个二元组《a,b》,M个三元组《c,d,e》,当b==e时,构成《a,c,d》,让后当不存在<u,v,w>,(u>=a,v>=b,w>=c),问存在几个元素。
思路:自己写一点都不会,题都看不懂。
首先基本思路是对于(a1,b1),(a2,b2),当b1==b2时,只留a最大的那个。
同理(c,d,e),当c、e相同时只留d最大的那个。
因为e必须要和b相同才能拼接成三元组,所以遍历输入(c,d,e)时就能把有效的(c,d,e)记录下来形成(a,d,e).
然后要去重和不合法的(a,d,e)。按a从大到小排序,用统计在平面直角坐标上x >= d和y>=e的地方是否出现过(a,d,e),没出现过即合法。
#include <iostream>#include <algorithm>#include <cstdio>#include <cmath>#include <cstring>#include <string>#define lowbit(x) (x&-x)typedef long long ll;typedef long long LL;using namespace std;const int INF=0x3f3f3f3f;const int MAXN=1010;int f[MAXN][MAXN];int zhi[MAXN][MAXN];int val[MAXN*100];int num[MAXN*100];ll sum[MAXN][MAXN];int main(){ int T; cin>>T; int cas = 1; while(T--) { memset(f,-1,sizeof(f)); memset(zhi,-1,sizeof(zhi)); memset(num,0,sizeof(num)); memset(val,0,sizeof(val)); memset(sum,0,sizeof(sum)); int n,m; cin>>n>>m; int x,y,z; while(n--) { scanf("%d%d",&x,&y); if(val[y]>x) continue; if(val[y]==x) num[y]++; if(val[y]<x) { val[y] = x; num[y] = 1; } } while(m--) { scanf("%d%d%d",&x,&y,&z); if(val[z]==0) continue; if(zhi[x][y]>val[z]) continue; if(zhi[x][y]==val[z]) sum[x][y]+=num[z]; if(zhi[x][y]<val[z]) { sum[x][y] = num[z]; zhi[x][y] = val[z]; } } ll ans = 0; for(int i=1000;i>0;i--) for(int j=1000;j>0;j--) { f[i][j] = max(f[i+1][j],f[i][j+1]); if(f[i][j]<zhi[i][j]) ans+=sum[i][j]; f[i][j] =max(f[i][j],zhi[i][j]); } printf("Case #%d: %lld\n",cas++,ans); } return 0;}
#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <queue>#include <algorithm>#include <iostream>#include <vector>using namespace std;#define LL long longconst int MAXN = 1e5 + 5;int id1[MAXN], cnt1[MAXN];struct P{ int c, d, e; LL v; P(){} P(int _c, int _d, int _e, LL _v){c = _c, d = _d, e = _e,v = _v;} bool operator == (const P &rbs)const { if(c == rbs.c && d == rbs.d && e == rbs.e) return true; return false; }}p[MAXN];bool cmp1(P u, P v){ if(u.c != v.c) return u.c < v.c; if(u.d != v.d) return u.d < v.d; return u.e < v.e;}const int MAXM = 1000 + 5;int tree[MAXM][MAXM];int lowbit(int a){ return a & -a;}void add(int x, int y, int val){ for(int i = x ; i <= 1000 ; i += lowbit(i)){ for(int j = y ; j <= 1000 ; j+= lowbit(j)) tree[i][j] += val; }}LL sum(int x, int y){ LL ans = 0; for(int i = x ; i > 0 ; i -= lowbit(i)){ for(int j = y ; j > 0 ; j -= lowbit(j)){ ans += tree[i][j]; } } return ans;}LL query(int x1, int y1, int x2, int y2){ return sum(x2, y2) - sum(x2, y1 - 1) - sum(x1 - 1, y2) + sum(x1 - 1, y1 - 1);}int main(){// freopen("HDU 5517.in", "r", stdin); int T; scanf("%d", &T); for(int cas = 1 ; cas <= T ; cas++){ int n, m; scanf("%d%d", &n, &m); memset(id1, -1, sizeof(id1)); int a, b, c; for(int i = 1 ; i <= n ; i++){ scanf("%d%d", &a, &b); if(id1[b] < a){ id1[b] = a; cnt1[b] = 1; } else if(id1[b] == a) cnt1[b]++; } int num = 0; for(int i = 0 ; i < m ; i++){ scanf("%d%d%d", &a, &b, &c); if(id1[c] != -1){ p[num++] = P(id1[c], a, b, cnt1[c]); } } sort(p, p + num, cmp1); n = 0; for(int i = 1 ; i < num ; i++){ if(p[n] == p[i]){ p[n].v += p[i].v; } else p[++n] = p[i]; }// for(int i = 0 ; i < n ; i++)// printf("i = %d, c = %d, d = %d, e = %d\n", i, p[i].c, p[i].d, p[i].e); memset(tree, 0, sizeof(tree)); LL ans = 0; for(int i = n ; i >= 0 ; i--){ if(!query(p[i].d, p[i].e, 1000, 1000)) ans += p[i].v; add(p[i].d, p[i].e, 1); } printf("Case #%d: %I64d\n", cas, ans); } return 0;}
阅读全文
0 0
- hdu5517 二维线段树
- HDU5517 沈阳现场赛 二维树状数组
- 二维线段树
- poj1656----二维线段树
- poj2155 二维线段树
- hdu1823 二维线段树
- POJ2155 二维线段树
- hdu1823 二维线段树
- HDU1823(二维线段树)
- poj2155 二维线段树
- CUGBACM_Summer_Tranning2【二维线段树】
- 二维线段树
- hdu1823 二维线段树
- hdu4819 二维线段树
- 二维线段树模版
- 二维线段树模板
- POJ2155二维线段树
- 二维线段树UVA11297
- PHP发送邮箱激活验证
- 解决Error inflating class android.support.design.widget.FloatingActionButton
- 分析知识,解决问题,设计方案
- Codeforces 241D : Numbers
- Springboot单元测试和Jdbctemplate的使用
- hdu5517 二维线段树
- 数学建模--图论(一)
- Django和Flask这两个框架在设计上各方面
- 使用JS打任意行金字塔练习
- javaweb项目从svn检出变成java项目
- Vivado的安装程序没反应怎么办
- 原生js遮罩层
- js获取url中的中文参数出现乱码解决方法
- 指针变量为什么可以作为“数组名”?