两次考试,两次惊魂
第一次尽管由于T2的SB操作丢了20分,但勉强从17分干到了15发,卡住了第一机房线
当我刚放松一些时,教练传来消息:下次考试后分机房
WTF?!?!?好吧继续考
T130min切掉(由于不会打暴力并没有对拍),T250pts暴力打完,又30min思考正解无果后还有1h,转战T3
T3明显的数位DP,然而由于状态定义错误调不出来,最后用3min打了个暴力扔上去
然后T3爆零了,原因是我把一个变量充定义然后它死循环了
当我看考完看着rank19的排名时,刚感觉要完戏,结果总榜一出,还是rank15?!
然后我就苟在了第一机房
怎么说呢,这段时间考试总是不在状态,尽管后期有了调整然而并不能挽回之前的失误
继续努力吧
0813:
T1:周
爆搜,不解释
T2:任
emmm.....这题我的思路和其他人不太一样,大概说一下
假设我们是一行一行来统计贡献,上一行的贡献为x,这一行的贡献是为多少
我们先处理出来每一行块数的前缀和sum,以及每一行和上一行连边数的前缀和link_x
那么显然我们这一行的贡献为sum-link_x,这个东西可以用二维前缀和维护,可以O(1)查询
然而这样会出问题,因为我们左边界的前缀和可能是错误的
我们可以处理出每列和左边相连的前缀和link_y来解决这个问题

#include<bits/stdc++.h> #define ll long long using namespace std; const int mx[4]={1,-1,0,0},my[4]={0,0,1,-1}; int n,m,q,ans,now,xxx,yyy,xx,yy,sol[2002][2002],slm[2002][2002],sim[2002][2002]; char s[2010][2010]; int main(){ scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=n;i++) scanf("%s",s[i]+1); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ sol[i][j]=sol[i][j-1]+sol[i-1][j]-sol[i-1][j-1]; if(s[i][j-1]!='1'&&s[i][j]=='1') sol[i][j]++; slm[i][j]=slm[i][j-1]+slm[i-1][j]-slm[i-1][j-1]; if(s[i][j]=='1'&&s[i-1][j]=='1') slm[i][j]++; sim[i][j]=sim[i-1][j]; if(s[i][j]==s[i][j-1]&&s[i][j]=='1') sim[i][j]++; } } while(scanf("%d%d%d%d",&xxx,&yyy,&xx,&yy)==4){ ans=sol[xx][yy]-sol[xxx-1][yy]-sol[xx][yyy-1]+sol[xxx-1][yyy-1]+sim[xx][yyy]-sim[xxx-1][yyy]; if(xx-xxx>=1) ans-=slm[xx][yy]-slm[xxx][yy]-slm[xx][yyy-1]+slm[xxx][yyy-1]; printf("%d\n",ans); } return 0; }
T3:飞
首先,我们仔细观察鬼畜值的定义,会惊奇的发现他让求的就是C(x,2),即两两相交的个数
又由于y单调递增,问题进一步转化为求逆序对数
然而这题卡内存,我们需要一些特殊的处理方法
我们发现X是由多段等差数列组成的
考虑等差数列中两项Xi和Xi+1的关联,发现Xi+1的答案就是Xi的答案-之前循环次数
因为之前每个数列必有一个数和Xi构成逆序对而和Xi+1构不成逆序对
对每个数列第一项特殊处理就好了
第一个不完整的数列需要加特判

#include<bits/stdc++.h> #define ll long long #define cri const register int #define re register using namespace std; ll c[100010],a; inline void add(cri x){ for(int i=x;i<=a;i+=i&-i) c[i]++; } inline ll get(cri x){ ll ans=0; for(int i=x;i>=1;i-=i&-i) ans+=c[i]; return ans; } int main(){ ll n,X,mod,x,lst,ans=0,num=0,i,lans; scanf("%lld%lld%lld%lld",&n,&X,&a,&mod); if(X<a) add(X+1); lst=X; x=(X+a)%mod; for(i=2;i<=n&&x>=a;i++){ lst=x; x+=a; if(x>=mod) x-=mod; } for(i;i<=n;i++){ if(x<a) ans+=(lst=i-1-(get(x+1))),num++,add(x+1); else ans+=(lst=lst-num+(x<X)); x+=a; if(x>=mod) x-=mod; } printf("%lld",ans); }
未完待续咕了