segment tree

监视任务

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define lson le,mid,root<<1
#define rson mid+1,rig,root<<1|1
using namespace std;
struct node{
  int l,r,k;
  bool operator<(const node &b) const{
    return r<b.r;
  }
}a[1000005];
int sum[500005<<2];
int book[500005];
void pushup(int root)
{
	sum[root]=sum[root<<1]+sum[root<<1|1]; 
} 
void build(int le,int rig,int root){
 if (le==rig) {
 	sum[root]=0;
 	return;
 }	
  int mid=(le+rig)>>1;
  build(lson);
  build(rson);
  pushup(root);
}

int query(int l,int r,int le,int rig,int root){
	if (l<=le&&r>=rig) return sum[root];
	int re=0;
	int mid=(le+rig)>>1;
	if (l<=mid) re+=query(l,r,lson);
	if (r>mid) re+=query(l,r,rson);
	return re;
}

void update(int pos,int le,int rig,int root){
	if (le==rig) {
		sum[root]=1;
		return;
	}
	int mid=(le+rig)>>1;
	if(pos<=mid) {
		update(pos,lson);
	}
	else {
		update(pos,rson);
	}
  pushup(root);
}
int main(){
   int n,m,ans;
   while (scanf("%d%d",&n,&m)!=EOF){
   	ans=0;
   	memset(book,0,sizeof(book));
   	for (int i=0;i<m;i++){
   		scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].k);
	   }
	build(1,n,1);
	sort(a,a+m);
	for (int i=0;i<m;i++){
		int pos=a[i].r;
		int cnt=query(a[i].l,a[i].r,1,n,1);
	   while (cnt<a[i].k){
	   	  while (book[pos]) pos--; 
	   	  book[pos]=1;
		  update(pos,1,n,1);
		  ans++;
		  cnt++; 
		 
	   }
	
	}
	printf("%d\n",ans);
   }	
	return 0;
}

contest

#include<cstdio>
#include<iostream>
#include<map>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=200010;
int c[maxn];
int n;
int a[maxn];
int cnt;
 
 
struct node2{
    int x,y,z;
}peo[200100];
 
 
struct node{
    int id;
    ll num;
}r[maxn];
 
int cmp(node x,node y)
{
   if (x.num!=y.num)
     return x.num<y.num;
   else
     return x.id<y.id;
}
int lowbit(int x){
    return x&(-x);
}
void add(int i,int value){
    while (i<=n){
        c[i]+=value;
        i+=lowbit(i);
    }
}
 
int sum(int i){
    int sum=0;
    while (i>=1){
        sum+=c[i];
        i-=lowbit(i);
    }
    return sum;
}
 
int main(){
    int t,i,tmp;
    ll ans;
      
     ans=0;
     while (scanf("%d",&n)!=EOF){
        for (int i=1;i<=n;i++)
          {
            scanf("%d%d%d",&peo[i].x,&peo[i].y,&peo[i].z);
          }
          memset(c,0,sizeof(c));
          memset(r,0,sizeof(r));
          for (int i=1;i<=n;i++)
           {
            r[i].num=peo[i].y;
            r[i].id=peo[i].x;
           }
           sort(r+1,r+n+1,cmp);
           for (int j=1;j<=n;j++)
             {
                add(r[j].id,1);
                ans+=j-sum(r[j].id);
             }
             memset(c,0,sizeof(c));
              
              
             for (int i=1;i<=n;i++){
                r[i].num=peo[i].z;
                r[i].id=peo[i].x;
             }
             sort(r+1,r+n+1,cmp);
             for (int j=1;j<=n;j++){
                add(r[j].id,1);
                ans+=j-sum(r[j].id);
             }
             memset(c,0,sizeof(c));
           
          for (int i=1;i<=n;i++)
          {r[i].num=peo[i].z;
           r[i].id=peo[i].y;
          }
          sort(r+1,r+n+1,cmp);
          for (int j=1;j<=n;j++)
            {
                add(r[j].id,1);
                ans+=j-sum(r[j].id);
            }
        printf("%lld\n",ans/2);
    }
    return 0;
     
}

sum

#include<cstdio>
#include<cstring>
#define clr(x)  memset(x,0,sizeof(x))
#define clr_1(x)  memset(x,-1,sizeof(x))
#define LL long long 
#define mod 1000000007
using namespace std;
const int N=1e5+10;
const int M=1e9+10;
int num[N];
int bit[35][N];
int n,m,k,u,v,op,t;
LL ans;

LL quick_pow(LL x,int n)
{
     LL res=1;
     while(n)
     {
         if(n&1) res=(res*x)%mod;
         x=(x*x)%mod;
         n>>=1;
     }
     return res;
 }
 void add(int i,int x,int pos)
 {
     while(i<=n)
     {
         bit[pos][i]+=x;
         i+=i&-i;
     }
     return ;
 }
 int sum(int i,int pos)
 {
     int s=0;
     while(i>0)
     {
         s+=bit[pos][i];
         i-=i&-i;
     }
     return s;
}



 int main()
{
    scanf("%d",&n);
    clr(bit);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&num[i]);
        k=0;
        t=num[i];
        while(t)
        {
            if(t&1) add(i,1,k);
            t>>=1;
            k++;
        }
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
     {
        scanf("%d%d%d",&op,&u,&v);
         if(op==1)
         {
             k=0;
             t=num[u];
             while(t)
             {
                 if(t&1) add(u,-1,k);
                 t>>=1;
                 k++;
             }
             num[u]=t=v;
             k=0;
             while(t)
             {
                 if(t&1) add(u,1,k);
                 t>>=1;
                 k++;
             }
         }
         if(op==2)
         {
            ans=0;
             for(k=0;k<=32;k++)
             {
                ans=(ans+(quick_pow(2,sum(v,k)-sum(u-1,k))-1)*quick_pow(2,k)%mod)%mod;
             }
             printf("%lld\n",ans);
         }
     }
     return 0;
 }

butterfly

#include<cstdio>
#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
#define lson rt<<1
#define rson rt<<1|1
const int INF = 1e9 + 7;
const int A = 2e3 + 10;
class TNode{
public:
	int l,r,Mx;
};

class Seg_Tree{
 public:
   TNode Tree[A<<3];
   
 void push_up(int rt){
 	Tree[rt].Mx=max(Tree[lson].Mx,Tree[rson].Mx);
 }
 
 void build_Tree(int rt,int l,int r){
 	Tree[rt].l=l;
 	Tree[rt].r=r;
 	Tree[rt].Mx=-INF;
 	if (l==r) return;
 	int mid=(l+r)>>1;
 	build_Tree(lson,l,mid);
 	build_Tree(rson,mid+1,r);
 	push_up(rt);
 }
 void update(int rt,int pos,int add){
 	int l=Tree[rt].l,r=Tree[rt].r;
 	if (l==r) {
 		Tree[rt].Mx=add;
 		return;
	 }
	 int mid=(l+r)>>1;
	 if (pos<=mid) update(lson,pos,add);
	 else          update(rson,pos,add);
	 push_up(rt);
 }
 int query(int rt,int st,int ed,int v){
 	int l=Tree[rt].l,r=Tree[rt].r;
 	if (l==r) return l;
 	int res=0;
 	
 	if(st<=l&&r<=ed){
 		if (Tree[rson].Mx>=v) res=query(rson,st,ed,v);
 		else if (Tree[lson].Mx>=v) res=query(lson,st,ed,v);
 		return res;
	 }
	 
	 int mid=(l+r)>>1;
	 if(ed>mid&&Tree[rson].Mx>=v) res=query(rson,st,ed,v);
	 if (res) return res;
	 if (st<=mid&&Tree[lson].Mx>=v) res=query(lson,st,ed,v);
	 return res;
 }
}T1,T2;

char s[A][A];
int dp[3][A][A];
int n,m;

int main(){
	scanf("%d%d",&n,&m);
	
	for (int i=1;i<=n;i++)
	 scanf("%s",s[i]+1); 
	 
	for (int i=n;i>=1;i--)
	 for (int j=1;j<=m;j++)
	 {
	 	if (s[i][j]!='X') continue;
	 	dp[0][i][j]=dp[0][i+1][j-1]+1;
	 	dp[1][i][j]=dp[1][i+1][j]+1;
		dp[2][i][j]=dp[2][i+1][j+1]+1; 
	 }
	 
	 int ans=0;
	 for (int i=1;i<=n;i++){
	 	T1.build_Tree(1,1,m);
	 	T2.build_Tree(1,1,m);
	 	
	 	for (int k=1;k<=m;k++){
	 		if (k&1) T1.update(1,k,min(dp[0][i][k],dp[1][i][k])-k-1);
	 		else     T2.update(1,k,min(dp[0][i][k],dp[1][i][k])-k-1);
		 }
		 
		 for (int j=1;j<=m;j++)
		  {
		  	if(s[i][j]!='X') continue;
		  	int pos=0,x=min(dp[1][i][j],dp[2][i][j]);
		  	if (x<=ans) continue;
		  	if (j&1) pos=T1.query(1,j,x+j-1,-j);
		  	else     pos=T2.query(1,j,x+j-1,-j);
		  	if (pos) ans=max(ans,pos-j+1);
 		  }
	 }
	printf("%d\n",ans);
	
	return 0;
}

the trip on …
数据范围很大,所以考虑使用线段树,考虑每次更新x到n加上y,然后i从x+1到n,每次更新i到n加上d,但是这样的复杂度会超时,因为每次更新的时候会多一个n,前缀和的做法,线段树和树状数组同时用,每次进行操作1的时候,用树状数组将这个点更新为y(用于处理首项和的问题)
,然后用线段树把整个【x+1,n】的值全部加上1(用于判断有多少个d的前缀和),然后操作二的时候,直接用树状数组统计一下x之前所有的和,实际上就是累加了多少个首项,然后用线段树取【1,x】里面的1然后乘以一个d就好了,最后加上a[i]就好,最后a[i]要减去这个值,

#include<cstdio>
#include<iostream>
#include<cstring> 
using namespace std;
typedef long long ll;
typedef double db;

const int maxn=1e5+5;
const int mod=1e9+7;
const int INF=1e8+7;
const int inf=1e15+8;

ll a[maxn];
ll c[maxn],n,d;

int lowbit(int x){
	return x&(-x);
} 

void up(int x,ll d){
	while (x<maxn){
		c[x]+=d;
		c[x]%=mod;
		x+=lowbit(x);
	} 
}
ll getsum(int x){
	int ans=0;
	while (x){
		ans+=c[x];
		c[x]%=mod;
		x-=lowbit(x);
	}
 return ans;
}

struct TREE{
	ll l,r,val,lazy;
	void fun(ll tmp){
		lazy+=tmp;
		val+=(r-l+1)*tmp;
	}
}tre[maxn*4];

void pushdown(int id){
	if (tre[id].lazy)
	  {
	  tre[id<<1].fun(tre[id].lazy);
      tre[id<<1|1].fun(tre[id].lazy);
      tre[id].lazy=0;
	  }
}

void pushup(int id){
	tre[id].val=tre[id<<1].val+tre[id<<1|1].val;
}

void build(int id,int l,int r){
   tre[id].l=l,tre[id].r=r,tre[id].lazy=0;
   if (l==r) tre[id].val=0;
   else{
   	int mid=(l+r)>>1;
   	build(id<<1,l,mid);
   	build(id<<1|1,mid+1,r);
   	pushup(id);
   }
}

void update(int id,int st,int ed,int val){
	int l=tre[id].l,r=tre[id].r;
	if (st<=l&&ed>=r) tre[id].fun(val);
	else {
		pushdown(id);
		int mid=(l+r)>>1;
		if (st<=mid) update(id<<1,st,ed,val);
		if (ed>mid) update(id<<1|1,st,ed,val);
		pushup(id);
	}
}
ll query(int id,int st,int ed){
	int l=tre[id].l,r=tre[id].r;
	if (st<=l&&ed>=r) return tre[id].val;
	else {
		pushdown(id);
		int mid=(l+r)>>1;
		ll sum1=0,sum2=0;
		if (st<=mid) sum1=query(id<<1,st,ed);
		if (ed>mid) sum2=query(id<<1|1,st,ed);
		pushup(id);
		return sum1+sum2;
	}
}
void solve(){
	int m;
	scanf("%lld%d%lld",&n,&m,&d);
	for (int i=1;i<=n;i++)
	  scanf("%lld",a+i);
	  
	memset(c,0,sizeof(c));
	build(1,1,n);
	ll tot=0;
	while (m--){
		int op,x,y;
		scanf("%d%d",&op,&x);
		if(op==1){
			scanf("%d",&y);
			up(x,y);
			update(1,x+1,n,1);
		}
		else {
			ll tmp=getsum(x)+query(1,1,x)*d+a[x];
			printf("%lld\n",tmp%mod);
			a[x]-=tmp;
		}
	}
	
	
}

int main(){
	int t=1;
	scanf("%d",&t);
	while (t--){
		solve();
	}
  return 0;
}
全部评论

相关推荐

在评审的大师兄很完美:像这种一般就是部门不匹配 转移至其他部门然后挂掉 我就是这样被挂了
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务