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;
}
签完上面六题就金了…
感冒喝了两罐兴奋剂感觉还是体力不支(比体力好选拔…)