20260208 总结
20260208 总结
spavanac
没什么好说的,m<0 就退位,n<0 就 \(+24\)。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
int main(){
file(spavanac);
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int n,m;
cin>>n>>m;
m-=45;
if(m<0)m+=60,--n;
if(n<0)n+=24;
cout<<n<<" "<<m<<"\n";
return 0;
}
zlagalica
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
const int maxn=230;
char ans[maxn][maxn];
int n,minx,miny,maxx,maxy,lstx,lsty;
struct card{
char c;
int r,s,u,d;
};
int main(){
file(zlagalica);
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
cin>>n;
vector<card>vec(n),tmp(n);
for(int i=0;i<n;i++)cin>>vec[i].c>>vec[i].r>>vec[i].s>>vec[i].u>>vec[i].d;
for(int i=0;i<n;i++){
int num;
cin>>num;
--num;
tmp[i]=vec[num];
}
vec.swap(tmp);
minx=maxx=210,miny=maxy=1;
for(int i=0;i<n;i++){
if(!i){
lstx=210,lsty=1;
}else{
if(!vec[i-1].u){
lstx-=vec[i-1].r;
lsty+=vec[i-1].d-1;
}else{
lstx-=vec[i-1].r-vec[i-1].d;
lsty+=vec[i-1].s;
}
}
for(int j=0;j<vec[i].r;j++)
for(int k=0;k<vec[i].s;k++)
ans[lstx-j][lsty+k]=vec[i].c,minx=min(minx,lstx-j),maxy=max(maxy,lsty+k);
}
cout<<maxx-minx+1<<" "<<maxy-miny+1<<"\n";
for(int i=minx;i<=maxx;i++){
for(int j=miny;j<=maxy;j++){
if(!ans[i][j])cout<<".";
else cout<<ans[i][j];
}
cout<<"\n";
}
return 0;
}
dirigent
but 并非老师的方法。
对于每个数,记 flag[i] 为当前数是否合法,即 \(flag_i\gets(a_{(i-1)\bmod n}\equiv a_i-1\land a_{(i+1)\bmod n}\equiv a_i+1)\pmod n\)。
如果所有的 flag[i] 都为 true,则 DA,否则 NE。
可以将 flag[i] 取反,记 cnt 为 \(\sum_{i=1}^nflag_i\),则若 \(cnt=0\),则 DA,否则 NE。
考虑每次修改会改变谁。改变下标集合为 \(\{x-1,x,x+1,y-1,y,y+1\}\pmod n\)。注意是集合。因为有个东西叫做集合互异性,万一一个下表改两次就麻烦大了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
int cnt,n,q;
const int maxn=3e5+5;
bitset<maxn>flag;
int arr[maxn],where[maxn];
int pre(int x){
return(x+n-2)%n+1;
}
int nxt(int x){
return x%n+1;
}
int main(){
file(dirigent);
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
cin>>n>>q;
for(int i=1;i<=n;i++)cin>>arr[i],where[arr[i]]=i;
auto changeflag=[&](int x){
flag[x]=!(arr[pre(x)]==pre(arr[x])&&arr[nxt(x)]==nxt(arr[x]));
};
for(int i=1;i<=n;i++){
changeflag(i);
cnt+=flag[i];
}
auto del=[&](int x){
cnt-=flag[x];
};
auto add=[&](int x){
changeflag(x);
cnt+=flag[x];
};
while(q--){
int x,y;
cin>>x>>y;
auto u=where[x],v=where[y];
swap(where[x],where[y]);
set<int>st={u,v,pre(u),pre(v),nxt(u),nxt(v)};
for(auto t:st)del(t);
swap(arr[u],arr[v]);
for(auto t:st)add(t);
if(!cnt)cout<<"DA\n";
else cout<<"NE\n";
}
return 0;
}
kuglice
考虑区间 DP。\(dp_{l,r,0/1}\) 表示区间 \(l\sim r\) 能做出的贡献。
考虑区间最后是谁拿的球。若区间长度为 \(sz\),则已经取出 \(n-sz\) 个球,则当前是 \(now(sz)=(n-sz)\operatorname{and}1\)(\(0\) 是 A,\(1\) 是 B)取球。
考虑转移(待会儿再看初始化):
设当前区间最后是 \(nw\) 拿的球,则:
考虑取最左边的球。如果这是序列中第一个此颜色的球并且序列中最后一个此颜色的球也被包含在区间 \([l,r]\) 内,则 lhs=dp[l+1][r][nw]+(l==tmp[a[l]][0]&&tmp[a[l]][1]<=r);
同理 rhs=dp[l][r-1][nw]+(r==tmp[a[r]][1]&&l<=tmp[a[r]][0])。
其实我们可以写个 query 函数:
auto query=[&](int l,int r,bool flag){
if(!flag&&l==tmp[a[l]][0])return tmp[a[l]][1]<=r;
if(flag&&r==tmp[a[r]][1])return l<=tmp[a[r]][0];
return false;
};
flag 表示取 lhs(flag=0)还是 rhs(flag=1)。
转移代码就是这样:
for(int siz=2;siz<=n;siz++){
auto nw=now(siz);
for(int l=1,r=l+siz-1;r<=n;++l,++r){
auto lhs=dp[l+1][r][nw]+query(l,r,0),rhs=dp[l][r-1][nw]+query(l,r,1);
if(lhs>rhs){
dp[l][r][nw]=lhs;
dp[l][r][!nw]=dp[l+1][r][!nw];
}else{
dp[l][r][nw]=rhs;
dp[l][r][!nw]=dp[l][r-1][!nw];
}
}
}
显然,初始化就是这样,因为 query(i,i,0)==query(i,i,1):
for(int i=1;i<=n;i++)dp[i][i][now(1)]=query(i,i,1);
AC code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
const int maxn=3005;
int a[maxn],n;
array<int,2>dp[maxn][maxn],tmp[maxn];
int main(){
file(kuglice);
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
cin>>n;
auto now=[&](int siz){
return((n-siz)&1);
};
for(int i=1;i<=n;i++)cin>>a[i],tmp[a[i]][0]=(!tmp[a[i]][0]?i:tmp[a[i]][0]),tmp[a[i]][1]=i;
auto query=[&](int l,int r,bool flag){
if(!flag&&l==tmp[a[l]][0])return tmp[a[l]][1]<=r;
if(flag&&r==tmp[a[r]][1])return l<=tmp[a[r]][0];
return false;
};
for(int i=1;i<=n;i++)dp[i][i][now(1)]=query(i,i,1);
for(int siz=2;siz<=n;siz++){
auto nw=now(siz);
for(int l=1,r=l+siz-1;r<=n;++l,++r){
auto lhs=dp[l+1][r][nw]+query(l,r,0),rhs=dp[l][r-1][nw]+query(l,r,1);
if(lhs>rhs){
dp[l][r][nw]=lhs;
dp[l][r][!nw]=dp[l+1][r][!nw];
}else{
dp[l][r][nw]=rhs;
dp[l][r][!nw]=dp[l][r-1][!nw];
}
}
}
cout<<dp[1][n][0]<<":"<<dp[1][n][1];
return 0;
}
最后说说死因:脑子没转过来,停止思考,上 ST 表。死于常数。
浙公网安备 33010602011771号