首页 > 代码库 > hdu 3874
hdu 3874
求一个序列中所有数字的和,其中数值相同的只能计算一次。
先储存所有的请求,然后按照它们的右边界排序,在查询的同时更新区间。这里其实有一点点DP的味道,在它进行某个查询之前,保证所有的重复数字(除去最后一个)都被删除光了,并且有不能影响其他查询,所以呢,只能从最近的那个操作进行计算。1次query即可
#include<iostream> #include<stdio.h> #include<string> #include<string.h> #include<algorithm> #include<vector> using namespace std; const int maxn = 50050; const int maxm = 200050; vector<int> vec; __int64 res[maxm]; __int64 ans; int pre[1000050]; void init() { vec.clear(); vec.push_back(0); memset(pre, 0, sizeof(pre)); } struct line{ int left, right, id; bool operator<(const line &y)const { return right < y.right; } }q[maxm]; struct node{ int left, right; __int64 sum; int mid(){ return (left+right)/2; } }tree[maxn*4]; void buildTree(int left, int right, int rt) { tree[rt].left = left; tree[rt].right = right; if(left == right){ int a; scanf("%d", &a); vec.push_back(a); return ; } int mid = tree[rt].mid(); buildTree(left, mid, rt<<1); buildTree(mid+1, right, rt<<1|1); tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum; } void update(int left, int right, int rt, int pos, int add) { if(left == right){ tree[rt].sum = add; return ; } int mid = tree[rt].mid(); if(pos <= mid) update(left, mid, rt<<1, pos, add); if(pos > mid) update(mid+1, right, rt<<1|1, pos, add); tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum; } void query(int left, int right, int rt, int L, int R) { if(L <= left && R >= right){ ans += tree[rt].sum; return ; } int mid = tree[rt].mid(); if(L <= mid) query(left, mid, rt<<1, L, R); if(R > mid) query(mid+1, right, rt<<1|1, L, R); } int main() { int T, M, N; scanf("%d", &T); while(T --) { scanf("%d", &N); init(); buildTree(1, N, 1); scanf("%d", &M); for(int i = 1; i <= M; i ++) { scanf("%d%d", &q[i].left, &q[i].right); q[i].id = i; } sort(q+1, q+M+1);//排序是从index=1开始的M个数 int qn = 0; for(int i = 1; i <= N && qn <=M; i ++) { if(pre[vec[i]] != 0){ update(1, N, 1, pre[vec[i]], 0); } update(1, N, 1, i, vec[i]); while(qn <= M && q[qn].right <= i){ ans = 0; if(q[qn].right == i){ query(1, N, 1, q[qn].left, q[qn].right); res[q[qn].id] = ans; } qn ++; } pre[vec[i]] = i; } for(int i = 1; i <= M; i ++) printf("%I64d\n", res[i]); } return 0; }
hdu 3874
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。