T1
考虑一个 n×nn\times nn×n 的矩阵 AAA,初始所有元素均为 000。 执行 q 次如下形式的操作:给定 444 个整数 r,c,l,sr,c,l,sr,c,l,s,对于每个满足 x∈[r,r+l),y∈[c,x−r+c]x ∈ [r,r+l), y ∈ [c,x−r+c]x∈[r,r+l),y∈[c,x−r+c] 的元素 (x,y)(x,y)(x,y),将权值增加 sss。也就是,给一个左上顶点为 (r,c)(r,c)(r,c)、直角边长为 lll 的下三角区域加 上 sss。 输出最终矩阵的元素异或和。
保证 n∈[1,103],q∈[0,3×105],r,c,l∈[1,n],s∈[1,109]n ∈ [1,10^3],q ∈ [0,3\times 10^5],r,c,l ∈ [1,n],s ∈ [1,10^9]n∈[1,103],q∈[0,3×105],r,c,l∈[1,n],s∈[1,109]。
挺简单的,就是二维前缀和,O(1)O(1)O(1)修改,n2n^2n2算答案
放上考场ACACAC代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 3005
#define LL long long
using namespace std;
int n,q;
LL row[maxn][maxn],line[maxn][maxn],a[maxn][maxn],ans;
inline int rd(){
int x=0,f=1;char c=' ';
while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
int main(){
freopen("u.in","r",stdin);
freopen("u.out","w",stdout);
n=rd(); q=rd();
while(q--){
int x=rd(),y=rd(),l=rd(),s=rd();
a[x][y]+=s; a[x+l][y]-=s;
line[x][y+1]-=s; line[x+l][y+l+1]+=s;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
line[i][j]+=line[i-1][j-1],a[i][j]+=a[i-1][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]+=a[i][j-1]+line[i][j],ans^=a[i][j];
printf("%lld\n",ans);
}
T2
有 nnn 个球排成一行,每个球的颜色为黑或白。 执行 kkk 次操作,第 i(1≤i≤k)i(1 ≤ i ≤ k)i(1≤i≤k) 次操作形式如下:
• 从 [1,n−i+1][1,n−i + 1][1,n−i+1] 中,等概率随机选择一个整数 xxx。
• 移除从左往右数的第 xxx 个球,或从右往左数的第 xxx 个球(也就是从左往右数的第 n−i+2−xn−i+2−xn−i+2−x 个)。之后,所有右侧的球的编号减 111。
给定每个球的颜色信息,希望最大化移除的白球数量。 输出在最优策略下,期望的移除白球数量。误差在 10−610^{-6}10−6 范围内,即算正确。
n≤30n\le 30n≤30,时限3000ms3000ms3000ms
solution:
就是一道期望的题,期望部分很简单,但是细节很多很复杂,可以用记搜实现,但是这是一道卡常神题,考场无人ACACAC,凭着优秀的常数拿到了969696分,但其实考场手懒都开的mapmapmap,前面242424位可以开数组,这样就可以拿满分了(什么zzzzzz题
先放上考场969696分代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#define maxn 35
#define LL long long
using namespace std;
int n,m,a[maxn];
char s[maxn];
double ans;
const double eps=1e-10;
LL bin;
map< pair<LL,int>,double > mp;
inline void work(int x){
x=n-x+1;
LL y=bin&((1LL<<x)-1);
bin=(bin^y)|((y&((1LL<<(x-1))-1))<<1);
}
inline int calc(LL x){
int cnt=0;
while(x){
if(x&1) cnt++;
x>>=1LL;
} return cnt;
}
inline double max(double x,double y){return x>y?x:y;}
double dfs(int now){
if(now==m+1 || bin==0) return 0.0;
if(mp[make_pair(bin,now)]>eps) return mp[make_pair(bin,now)];
double res=0.0,qwq; LL tmp=bin; int x;
for(int i=1;i<=n-now+1;i++){
x=(bin&(1LL<<(n-i)))?1:0; work(i);
qwq=(x+dfs(now+1))*1.0/(n-now+1);
bin=tmp;
x=(bin&(1LL<<(now-2+i)))?1:0; work(n-now+2-i);
qwq=max(qwq,(x+dfs(now+1))*1.0/(n-now+1));
bin=tmp;
res+=qwq;
}
return mp[make_pair(bin,now)]=res;
}
int main(){
// freopen("in.txt","r",stdin);
// freopen("out2.txt","w",stdout);
// freopen("v.in","r",stdin);
// freopen("v.out","w",stdout);
scanf("%d%d%s",&n,&m,s+1);
int ccnt=0;
for(int i=1;i<=n;i++)
a[i]=(s[i]=='W')?1:0,bin=(bin<<1LL)|a[i],ccnt+=a[i];
if(m==n) return printf("%.10lf\n",(double)ccnt),0;
printf("%.10lf\n",dfs(1));
return 0;
}
然后是改完的(其实就差那么一步啊
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<unordered_map>
#define maxn 35
#define LL long long
using namespace std;
int n,m,a[maxn];
char s[maxn];
double ans,f[(1<<24)+5];
const double eps=1e-10;
LL bin,num;
unordered_map< LL,double > mp[31];
inline void work(int x,int len){
x=len-x+1;
int y=bin&((1<<(x-1))-1);
bin=((bin>>x)<<(x-1))|y;
}
inline int calc(int len){
int cnt=0;
for(int i=1;i<=len;i++)
cnt+=a[i];
return cnt;
}
double dfs(int now){
if(now==m+1 || bin==0) return 0.0;
double res=0.0; LL tmp=bin;
int len=n-now+1;
if(len<24 && f[1<<len|bin]!=-1) return f[1<<len|bin];
if(mp[now].count(bin)) return mp[now][bin];
for(int i=1;i<=(len+1)/2;i++){
double qwq=0.0;
int x=(bin>>(len-i))&1; work(i,len);
if((len&1) && i==(len+1)/2)
qwq=(x+dfs(now+1))*1.0/len;
else qwq=(x+dfs(now+1))*2.0/len;
bin=tmp;
x=(bin>>(len-(n-now+2-i)))&1; work(n-now+2-i,len);
if((len&1) && i==(len+1)/2)
qwq=max(qwq,(x+dfs(now+1))*1.0/len);
else qwq=max(qwq,(x+dfs(now+1))*2.0/len);
bin=tmp;
res+=qwq;
}
if(len<24) return f[1<<len|bin]=res;
else return mp[now][bin]=res;
}
int main(){
freopen("v.in","r",stdin);
freopen("v.out","w",stdout);
scanf("%d%d%s",&n,&m,s+1); int ccnt=0;
for(int i=1;i<=n;i++)
a[i]=(s[i]=='W')?1:0,bin=(bin<<1LL)|a[i],ccnt+=a[i];
if(m==n) return printf("%.10lf\n",(double)ccnt),0;
for(int i=1;i<(1<<24);i++) f[i]=-1;
printf("%.10lf\n",dfs(1));
return 0;
}
还听ghostcaighostcaighostcai的用了c++11c++11c++11的unordered_mapunordered\_mapunordered_map但好像没什么卵用
顺便说大力卡常以后极限数据只跑了1.8ms1.8ms1.8ms呢qwqqwqqwq
T3
树形dpdpdp,完了有时间改吧···
总分100+96+5(如果不CE)=201100+96+5(如果不CE)=201100+96+5(如果不CE)=201,好像可以稍微拯救一下我跌下去的均分???