时间非常充裕,但是还是不会T3=_=
开始通读一遍题,然后发现T2非常友善地告诉我们要写最长不降(不升)子序列,而且数据才到2000(小可爱),那么就都跑一边比个大小就行(大约40min)
再看T1与T3,T3要用线段树,就先写个暴力(大概十多分钟?)在去写T1。一开始想的是贪心,先写了两个特判,但很快就发现DFS可行写完用大约30分钟,调试大约十分钟(加了一句边界)。
接下来开始乱搞,试着写了一下树状数组,但是WA掉了(还剩半个多小时),只好去卡常,加快读——结束
T1:
#include<bits/stdc++.h>
using namespace std;
int n,k,ans;
int dfs(int x)
{
if(n>=x) return n-x;
if(x%2==1) return min(dfs(x+1)+1,dfs(x-1)+1);
else return min(dfs(x/2)+1,x-n);
}
int main()
{
//freopen("catchcow.in","r",stdin);
//freopen("catchcow.out","w",stdout);
scanf("%d%d",&n,&k);
if(n==k)
{
printf("0");
return 0;
}
else if(k<n)
{
printf("%d",n-k);
return 0;
}
ans=dfs(k);
printf("%d",ans);
return 0;
}
不过dfs写最差数据到1e6的题实在是有问题的,这种情况下如果时间充足还是应该用BFS保险
#include<bits/stdc++.h>
using namespace std;
int n,k,vis[1000010];
queue<int>q;
void bfs()
{
while(1)
{
int x=q.front();
q.pop();
if(x+1<=1e6&&vis[x+1]==-1)
{
vis[x+1]=vis[x]+1;
q.push(x+1);
}
if(x-1<=1e6&&vis[x-1]==-1)
{
vis[x-1]=vis[x]+1;
q.push(x-1);
}
if(x*2<=1e6&&vis[x*2]==-1)
{
vis[x*2]=vis[x]+1;
q.push(x*2);
}
if(vis[k]!=-1) break;
}
}
int main()
{
//freopen("catchcow.in","r",stdin);
//freopen("catchcow.out","w",stdout);
memset(vis,-1,sizeof vis);
scanf("%d%d",&n,&k);
q.push(n);
vis[n]=0;
bfs();
printf("%d",vis[k]);
return 0;
}
T2:就裸的最长...子序列,b1,b2 是按升序降序排的原数组
T3:教主的魔法
暴力碾标算hhhh回来说正解,emmm就明显线段树,但还是写的不熟练中间卡过的几个地方:第33,41,75,98行,其余都是手误了。还有就是数据与题目不符,其实完全可以
#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
struct node
{
int min1,max1,flag;
} tree[N*4];
int n,q,a[N],l,r,c;
char ch;
int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(ch=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
void update(int p)
{
tree[p].max1=max(tree[p<<1].max1,tree[p<<1|1].max1);
tree[p].min1=min(tree[p<<1].min1,tree[p<<1|1].min1);
}
inline void pushdown(int p)
{
if(tree[p].flag)
{
tree[p<<1].flag+=tree[p].flag;
tree[p<<1].max1+=tree[p].flag;
tree[p<<1].min1+=tree[p].flag;
tree[p<<1|1].flag+=tree[p].flag;
tree[p<<1|1].max1+=tree[p].flag;
tree[p<<1|1].min1+=tree[p].flag;
tree[p].flag=0;
}
}
void build(int p,int l,int r)
{
if(l==r)
{
tree[p].min1=tree[p].max1=a[l];
return ;
}
int mid=(l+r)/2;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
update(p);
}
void add_edge(int p,int l,int r,int ql,int qr,int c)
{
if(ql<=l and r<=qr)
{
tree[p].max1+=c;
tree[p].min1+=c;
tree[p].flag+=c;
return ;
}
pushdown(p);
int mid=(l+r)/2;
if(ql<=mid) add_edge(p<<1,l,mid,ql,qr,c);
if(mid<qr) add_edge(p<<1|1,mid+1,r,ql,qr,c);
update(p);
}
int qeury(int p,int l,int r,int ql,int qr,int c)
{
if(ql<=l&&r<=qr&&c<=tree[p].min1) return r-l+1;
if(ql<=l&&r<=qr&&c>tree[p].max1) return 0;
pushdown(p);
int mid=(l+r)/2,ans=0;
if(ql<=mid) ans+=qeury(p<<1,l,mid,ql,qr,c);
if(mid<qr) ans+=qeury(p<<1|1,mid+1,r,ql,qr,c);
update(p);
return ans;
}
int main()
{
//freopen("magic.in","r",stdin);
//freopen("magic.out","w",stdout);
//std::ios::sync_with_stdio(0);
n=read();
q=read();
for(int i=1; i<=n; ++i) a[i]=read();
build(1,1,n);
while(q--)
{
cin>>ch;
l=read();
r=read();
c=read();
if(ch=='M') add_edge(1,1,n,l,r,c);
else printf("%d\n",qeury(1,1,n,l,r,c));
}
return 0;
}