https://cn.vjudge.net/contest/234556#problem/D
裸的线段树
代码:
#include<bits/stdc++.h>
#define ll unsigned long long
#define inf 1e9+7
using namespace std;
int a[200005];
struct node
{
int sum;
}v[200005<<2];
void build(int k,int l,int r)
{
int mid;
if(l==r)
{
v[k].sum=a[l];
}
else
{
mid=(l+r)>>1;
build((k<<1),l,mid);
build((k<<1)+1,mid+1,r);
v[k].sum=v[(k<<1)].sum+v[(k<<1)+1].sum;
}
}
void update(int k,int l,int r,int pos,int val)
{
if(l==r)
{
v[k].sum=val;
}
else
{
int mid;
mid=(l+r)>>1;
if(pos<=mid)
update((k<<1),l,mid,pos,val);
else
update((k<<1)+1,mid+1,r,pos,val);
v[k].sum=v[(k<<1)].sum+v[(k<<1)+1].sum;
}
}
int get(int k,int l,int r,int ls,int rs)
{
if(ls<=l&&rs>=r)
return v[k].sum;
else
{
int mid;
mid=(l+r)>>1;
int ans;
ans=0;
if(ls<=mid)
ans+=get((k<<1),l,mid,ls,rs);
if(rs>mid)
ans+=get((k<<1)+1,mid+1,r,ls,rs);
return ans;
}
}
int main()
{
int n,i,j,aa,bb,k;
k=0;
while(scanf("%d",&n)&&n)
{
if(k)
printf("\n");
k++;
string s;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,1,n);
printf("Case %d:\n",k);
while(cin>>s&&s[0]!='E')
{
if(s[0]=='S')
{
scanf("%d%d",&aa,&bb);
update(1,1,n,aa,bb);
}
else
{
scanf("%d%d",&aa,&bb);
printf("%d\n",get(1,1,n,aa,bb));
}
}
}
}
https://cn.vjudge.net/contest/234556#problem/F
跟上一个题一样都是裸的线段树不用思考
代码:
#include<bits/stdc++.h>
#define ll unsigned long long
#define inf 1e9+7
using namespace std;
int a[100005];
struct node
{
int sum;
}v[100005<<2];
void build(int k,int l,int r)
{
int mid;
if(l==r)
{
v[k].sum=a[l];
}
else
{
mid=(l+r)>>1;
build((k<<1),l,mid);
build((k<<1)+1,mid+1,r);
v[k].sum=min(v[(k<<1)].sum,v[(k<<1)+1].sum);
}
}
void update(int k,int l,int r,int pos,int val)
{
if(l==r)
{
v[k].sum=val;
}
else
{
int mid;
mid=(l+r)>>1;
if(pos<=mid)
update((k<<1),l,mid,pos,val);
else
update((k<<1)+1,mid+1,r,pos,val);
v[k].sum=min(v[(k<<1)].sum,v[(k<<1)+1].sum);
}
}
int get(int k,int l,int r,int ls,int rs)
{
if(ls<=l&&rs>=r)
return v[k].sum;
else
{
int mid;
mid=(l+r)>>1;
int ans;
ans=inf;
if(ls<=mid)
ans=min(ans,get((k<<1),l,mid,ls,rs));
if(rs>mid)
ans=min(ans,get((k<<1)+1,mid+1,r,ls,rs));
return ans;
}
}
int main()
{
int n,i,j,aa,bb,k,q,b[50];
k=0;
scanf("%d%d",&n,&q);
string s;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,1,n);
while(q--)
{
//cout<<"sssss"<<endl;
cin>>s;
if(s[0]=='q')
{
aa=bb=0;
i=6;
while(s[i]>='0'&&s[i]<='9')
{
aa=(aa*10)+(s[i]-'0');
i++;
}
i++;
while(s[i]>='0'&&s[i]<='9')
{
bb=(bb*10)+(s[i]-'0');
i++;
}
printf("%d\n",get(1,1,n,aa,bb));
}
else
{
int m;
m=s.size();
for(i=6,j=0;i<m;i++)
{
aa=0;
while(s[i]>='0'&&s[i]<='9')
{
aa=(aa*10)+(s[i]-'0');
i++;
}
b[j++]=aa;
}
int ans;
ans=get(1,1,n,b[0],b[0]);
for(i=1;i<j;i++)
{
int tt;
tt=get(1,1,n,b[i],b[i]);
update(1,1,n,b[i-1],tt);
}
update(1,1,n,b[i-1],ans);
}
}
}
https://cn.vjudge.net/contest/234556#problem/P
假的线段树,可以直接暴力
代码:
#include<bits/stdc++.h>
#define ll unsigned long long
#define inf 1e9+7
using namespace std;
int a[200005];
int vis[10005];
int main()
{
int n,i,t,q,aa,bb,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&aa,&bb);
if(bb-aa>10000)
printf("0\n");
else
{
//memset(vis,0,sizeof(vis));
for(i=aa,j=0;i<=bb;i++,j++)
{
vis[j]=a[i];
}
sort(vis,vis+j);
int maxn=inf;
for(i=1;i<j;i++)
{
if(vis[i]-vis[i-1]<maxn)
maxn=vis[i]-vis[i-1];
}
printf("%d\n",maxn);
}
}
}
}
还有一个题,还没有做出来TLE,我打算用二分和线段树优化。。。明天继续