• 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
    ", res[i]);
    	}
    	
    	return 0;
    } 


  • 相关阅读:
    ⑤SpringBoot之定时任务
    ④SpringBoot之thymeleaf使用
    ③SpringBoot中Redis的使用
    ②SpringBoot之Web综合开发
    Redis、Memcache和MongoDB
    ADB常用命令 & 无线调试Debug黑科技
    Flutter生命周期
    Flutter-Tips
    Git rebase命令
    Git 恢复本地误删的文件
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4252087.html
Copyright © 2020-2023  润新知