zoukankan      html  css  js  c++  java
  • 【newSSLOJ1298】网站计划【线段树】

    题目大意:

    题目链接:http://10.156.31.134/contestnew.aspx?cid=77 (学校局域网)
    有一个数列a[]a[],给出mmli,ril_i,r_i,每次在a[liri]a[l_isim r_i]中选择最大的数字kk,得到权值(li+ri)×k(l_i+r_i) imes k,并把该数字改成0。求最终权值。


    思路:

    要求支持查询区间最大值和单点修改。线段树不解释了。
    tree[x].maxntree[x].maxn表示这段区间的最大值,tree[x].wtree[x].w表示最大值所在的位置。


    代码:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    const int N=200010;
    int n,m,l,r,ans,a[N];
    
    struct Tree
    {
    	int l,r,maxn,w;
    }tree[N*4];
    
    int read()
    {
    	int d=0,f=1;
    	char ch=getchar();
    	while (ch<'0'||ch>'9')
    	{
    		ch=getchar();
    		if (ch=='-') f=-1;
    	}
    	while (ch>='0'&&ch<='9')
    		d=(d<<3)+(d<<1)+ch-48,ch=getchar();
    	return d*f;
    }
    
    void build(int x)
    {
    	if (tree[x].l==tree[x].r)
    	{
    		tree[x].maxn=a[tree[x].l];
    		tree[x].w=tree[x].l;
    		return;
    	}
    	int mid=(tree[x].l+tree[x].r)/2;
    	tree[x*2].l=tree[x].l;
    	tree[x*2].r=mid;
    	tree[x*2+1].l=mid+1;
    	tree[x*2+1].r=tree[x].r;
    	build(x*2);
    	build(x*2+1);
    	if (tree[x*2].maxn>=tree[x*2+1].maxn)  //合并
    	{
    		tree[x].maxn=tree[x*2].maxn;
    		tree[x].w=tree[x*2].w;
    	}
    	else
    	{
    		tree[x].maxn=tree[x*2+1].maxn;
    		tree[x].w=tree[x*2+1].w;
    	}
    }
    
    pair<int,int> ask(int x,int l,int r)  //询问,回答时回答最大值和它所在位置
    {
    	if (tree[x].l==l&&tree[x].r==r)
    		return make_pair(tree[x].maxn,tree[x].w);
    	if (tree[x].l==tree[x].r) return make_pair(0,0);
    	int mid=(tree[x].l+tree[x].r)/2;
    	if (r<=mid) return ask(x*2,l,r);
    	if (l>mid) return ask(x*2+1,l,r);
    	//return max(ask(l,mid),ask(mid+1,r));
    	pair<int,int> x1=ask(x*2,l,mid),x2=ask(x*2+1,mid+1,r);
    	if (x1.first>=x2.first) return x1;
    		else return x2;
    }
    
    void change(int x,int k)
    {
    	if (tree[x].l==k&&tree[x].r==k)
    	{
    		tree[x].maxn=0;
    		return;
    	}
    	if (tree[x].l==tree[x].r) return;
    	int mid=(tree[x].l+tree[x].r)/2;
    	if (k<=mid) change(x*2,k);
    		else change(x*2+1,k);
    	if (tree[x*2].maxn>=tree[x*2+1].maxn)
    	{
    		tree[x].maxn=tree[x*2].maxn;
    		tree[x].w=tree[x*2].w;
    	}
    	else
    	{
    		tree[x].maxn=tree[x*2+1].maxn;
    		tree[x].w=tree[x*2+1].w;
    	}
    }
    
    int main()
    {
    	//scanf("%d%d",&n,&m);
    	n=read(),m=read();
    	for (int i=1;i<=n;i++)
    		//scanf("%d",&a[i]);
    		a[i]=read();
    	tree[1].l=1;
    	tree[1].r=n;
    	build(1);
    	while (m--)
    	{
    		//scanf("%d%d",&l,&r);
    		l=read(),r=read();
    		pair<int,int> maxx=ask(1,l,r);
    		ans=(ans+((l+r)%2011)*(maxx.first%2011))%2011;
    		change(1,maxx.second);
    	}
    	printf("%d",ans%2011);
    	return 0;
    }
    
  • 相关阅读:
    SVN使用方法
    NHiberante3.2 调用存储过程之Errors in named queries:
    AjaxFileUpload + *.ashx 文件上传在IE8.0(XP,VS2010,Development Server)下的注意
    PB中设置SQLCA.AutoCommit = False的说明
    UrlRoutingModel摘要
    PB中的大数据量插入操作测试
    PB TreeView控件
    关于端口共用
    关于RealProxy
    EF无法更新错误
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998302.html
Copyright © 2011-2022 走看看