模拟测试20190813(下)+14

两次考试,两次惊魂

第一次尽管由于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
",ans);
    }
    return 0;
}
View Code

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);

}
View Code

未完待续咕了

 

原文地址:https://www.cnblogs.com/mikufun-hzoi-cpp/p/11355716.html