19 银川 icpc

N

出题人让每个人有气球

I

wqq带的板子,进制转换

B

给一个大矩阵,其实只要三个点贡献瞎搞搞

G

维护四个素数线段树,乘即是加(我要是没打错板子就银了(没要是…

F

1e6以下暴力,1e6以上推式子O(1) 即可,(虽然队友最后推出规律推出式子,但只有五分钟了)

/*   Author : Rshs
 *   Data : 2019-11-30-06.43
 */
#include<bits/stdc++.h>
using namespace std;
#define FI first
#define SE second
#define LL long long
#define MP make_pair
#define PII pair<int,int>
#define SZ(a) (int)a.size()
const double pai = acos(-1);
const double eps = 1e-10;
const LL mod = 998244353;
const int MXN = 1e6+5;
void exgcd(LL a,LL b,LL &x,LL &y,LL &d){ //欧几里得函数 求解ax+by=gcd(a,b)的一组解 d=gcd(a,b)
    if(b==0){d=a,x=1,y=0;return;}
    exgcd(b,a%b,y,x,d); //x=y0,y=x0-a/b*y0
    y-=x*(a/b);
}
LL inv(LL t, LL p){                   //返回t对p的逆元
    LL d,x,y;
    exgcd(t,p,x,y,d);
    return (x%p+p)%p;        //x可能为负,也可能过大
}
LL f(LL n){
    return n%mod*((n+1)%mod)%mod*((2*n+1)%mod)%mod*inv(6,mod)%mod;
}
LL pa(LL n){
    return ((n+1)%mod)*(n%mod)%mod*inv(2,mod)%mod;
}
int main(){//cout<<f(3);
    LL n;cin>>n;

    LL ans=0;
    for(LL i=2;i<=min((LL)1e6,n);i++){
        for(LL j=i,c=1;j<=n;j=j*i,c++){
            LL up=min(j*i-1,n);
            ans=(ans+(up-j+1)%mod*i%mod*c%mod)%mod;
        }
    }
    if(n<=1e6) return cout<<ans<<'\n',0;
    ans=ans+n%mod*pa(n-1e6)%mod-f(n-1e6)+pa(n-1e6);
    ans%=mod;
    ans+=mod;
    ans%=mod;
    cout<<ans<<'\n';
    return 0;
}

K

又又又掉进想当然误区(小改wa两次就去想是不是读错题还是思路错了…)
但是也和标准答案差不多了。
先预处理每个点向下延申的最远距离,然后从上到下从左到右扫a,遇到相同的平行的一段就跑单调栈。

/*   Author : Rshs
 *   Data : 2019-10-21-12.59
 */
#include<bits/stdc++.h>
using namespace std;
#define FI first
#define SE second
#define LL long long
#define MP make_pair
#define PII pair<int,int>
#define SZ(a) ((int)a.size())
const double pai = acos(-1);
const double eps = 1e-10;
const LL mod = 1e9+7;
const int MXN = 1e6+5;
int a[1005][1005],b[1005][1005],dp[1005][1005];
PII id[1005*1005];
int lto[1005],rto[1005];
int ff(int l,int r,int h){
    int re=0;
    stack<int>sk;
    for(int i=l;i<=r;i++) {
        while(!sk.empty()&&dp[h][sk.top()]>=dp[h][i]) sk.pop();
        if(sk.empty()) lto[i]=l-1;
        else lto[i]=sk.top();
        sk.push(i);
    }
    while(!sk.empty())sk.pop();
    for(int i=r;i>=l;i--) {
        while(!sk.empty()&&dp[h][sk.top()]>=dp[h][i]) sk.pop();
        if(sk.empty()) rto[i]=r+1;
        else rto[i]=sk.top();
        sk.push(i);
    }
    for(int i=l;i<=r;i++){
        re=max(re,(rto[i]-lto[i]-1)*dp[h][i]);
    }
    return re;
}
int main(){
    int n,m;cin>>n>>m;
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)scanf("%d",&a[i][j]);
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)scanf("%d",&b[i][j]),id[b[i][j]]=MP(i,j);
    for(int i=1;i<=m;i++) dp[n][i]=1;
    for(int i=n-1;i>=1;i--) {
        for(int j=1;j<=m;j++){
            auto now=id[a[i][j]];
            if(b[now.FI+1][now.SE]==a[i+1][j]) dp[i][j]=dp[i+1][j]+1;
            else dp[i][j]=1;
        }
    }
    /*for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++) cout<<dp[i][j]<<' ';
        puts("");
    }*/
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            int last=j;
            auto now=id[a[i][j]];
            while(j<m&&now.SE<m&&a[i][j+1]==b[now.FI][now.SE+1]) j++,now.SE++;
            ans=max(ans,ff(last,j,i));
        }
    }
    cout<<ans;
    return 0;
}

签完上面六题就金了…
感冒喝了两罐兴奋剂感觉还是体力不支(比体力好选拔…)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值