D2
T1
就是一道比较好想的dp题啦,一开始是想开三维询问最大最小值,但后来发现预处理个ST表O(1)查询就可以省下一维啦,题解的做法和我的有点点不一样呐,题解上市倒着枚举的然后就可以线性递推维护最大最小值了,题解时间复杂度为(nm),我的做法的时间复杂度为(nlogn+nm),在m较大时可以忽略为O(nm),可能会慢一点点但很好想也好些。然后考试的时候一不小心把min(mini[l][k],mini[r-(1<<k)+1][k])写成了min(mini[l][k],maxi[r-(1<<k)+1][k])orz,然后全班这道题就我没A(吧?)QAQ
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <queue>
#define inf 0x7ffffffffff
#define maxn 20005
#define maxm 1005
using namespace std;
int n,m,k;
int mini[maxn][21],maxi[maxn][21];
long long dp[maxn];
int read()
{
int xx=0,kk=1;char ch=' ';
while(!isdigit(ch)){ch=getchar();if(ch=='-')kk=-1;}
while(isdigit(ch)){xx=xx*10+ch-'0';ch=getchar();}
return kk*xx;
}
inline int qmax(int l,int r)
{
int k=log(r-l+1);
return max(maxi[l][k],maxi[r-(1<<k)+1][k]);
}
inline int qmin(int l,int r)
{
int k=log(r-l+1);
return min(mini[l][k],mini[r-(1<<k)+1][k]);
}
int main()
{
freopen("toy.in","r",stdin);
freopen("toy.out","w",stdout);
n=read(),m=read(),k=read();
for(int i=1;i<=n;++i)
maxi[i][0]=mini[i][0]=read();
for(int j=1;j<=log(n)+1;++j)
for(int i=1;i+(1<<j)-1<=n;++i)
{
maxi[i][j]=max(maxi[i][j-1],maxi[i+(1<<(j-1))][j-1]);
mini[i][j]=min(mini[i][j-1],mini[i+(1<<(j-1))][j-1]);
}
for(int i=1;i<=n;++i) dp[i]=inf;
for(int i=1;i<=n;++i)
for(int l=1;l<=m&&l+i-1<=n;++l)
{
int j=i+l-1;
dp[j]=min(dp[j],dp[i-1]+1ll*l*(qmax(i,j)-qmin(i,j))+1ll*k);
}
printf("%lld",dp[n]);
return 0;
}
T2
考试的时候想出了正解!!(我可真是个小天才)
但我偷懒吧用dep[u]和dep[v]的关系来决定该边有没有做贡献,然后后面可能修改到的某条边与dep[u],dep[v]完全没有关系!这样判断就会导致某些边使得cnt[v]更新多次,然后gg。所以以后还是不要偷懒啦!!
然后之后改判边修改过没的时候,一个地方要把我改死啦!!就是那该死的位运算的优先级,(r-1)<<1+1运算出来的结果不是((r-1)<<1)+1而是(r-1)<<(1+1)(呕)。果然以后位运算能打括号的地方还是都尽量要打上哒QwQ
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <queue>
#define inf 0x7fffffff
#define maxn 100010
#define maxm 200010
using namespace std;
bool vis[maxn<<1];
int n,m,q,u,v,num,ans,r;
int fir[maxn],dot[maxm][2],cnt[maxn],dep[maxn];
queue<int> que;
struct qwq
{
int to,nxt;
}e[maxm<<1];
int read()
{
int xx=0,kk=1;char ch=' ';
while(!isdigit(ch)){ch=getchar();if(ch=='-')kk=-1;}
while(isdigit(ch)){xx=xx*10+ch-'0';ch=getchar();}
return kk*xx;
}
void addedge(int u,int v)
{
e[num].to=v;
e[num].nxt=fir[u];
fir[u]=num++;
}
void bfs()
{
que.push(1);dep[1]=1;
while(!que.empty())
{
int u=que.front();que.pop();
for(int i=fir[u];i!=-1;i=e[i].nxt)
{
int v=e[i].to;
if(dep[v]==dep[u]+1) cnt[v]++;
if(!dep[v])
dep[v]=dep[u]+1,cnt[v]=1,que.push(v);
}
}
}
void modify(int u,int edge)
{
if(!cnt[u]||vis[edge]||vis[edge^1]) return;
vis[edge]=vis[edge^1]=true;
if(--cnt[u]==0) ans++;
else return;
for(int i=fir[u];i!=-1;i=e[i].nxt)
{
int v=e[i].to;
if(dep[u]<dep[v])
modify(v,i);
}
}
int main()
{
freopen("train.in","r",stdin);
freopen("train.out","w",stdout);
n=read(),m=read(),q=read();
memset(fir,-1,sizeof(fir));
for(int i=1;i<=m;++i)
{
u=read(),v=read();
addedge(u,v);addedge(v,u);
dot[i][0]=u,dot[i][1]=v;
}
bfs();cnt[1]=inf;
while(q--)
{
r=read();
int d0=dot[r][0];
int d1=dot[r][1];
if(dep[d0]==dep[d1]||vis[(r-1)<<1]||vis[((r-1)<<1)+1])
{
printf("%d\n",ans);
continue;
}
if(dep[d0]>dep[d1]) swap(d0,d1);
modify(d1,(r-1)<<1);
printf("%d\n",ans);
}
return 0;
}
T3
辣鸡数据结构!还没改完!
TO BE CONTINUED...