C
题意:求A*B+C=N
A,B,C种类个数
#include <bits/stdc++.h>
#define int long long
//#pragma GCC optimize(2)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
void solve()
{
int sum=0;
int N;
cin>>N;
for(int i=1;i<N;i++)
{
sum+=(N-1)/i;
}
cout<<sum;
}
signed main() {
int _=1;
while(_--) {
solve();
}
return 0;
}
#include <bits/stdc++.h>
//#define int long long
//#pragma GCC optimize(2)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
int dp[maxn];
void init()
{
dp[1]=1;
dp[2]=2;
dp[3]=2;
for(int i=4;i<maxn;i++){
int xx=i;
int sum=1;
for(int j=2;j*j<=xx;j++)
{
int ans=1;
while(xx%j==0)
{
ans++;
xx/=j;
}
sum*=ans;
}
if(xx!=1)
sum*=2;
dp[i]=sum;
}
}
void solve()
{
int sum=0;
int n;
cin>>n;
for(int i=1;i<n;i++)
{
int xx=n-i;
sum+=dp[xx];
}
cout<<sum;
}
int main() {
int _=1;
while(_--) {
init();
solve();
}
return 0;
}
D
题意:
1-n
可以走k个不相交的区间,问到n的路径有几种情况。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=2e5+5;
const int mod=998244353;
vector<pair<int,int> >vv;
int dp[maxn]={0};
int sum[maxn]={0};
void solve()
{
vv.clear();
int n,k;
cin>>n>>k;
for(int i=1;i<=k;i++)
{
int l,r;
cin>>l>>r;
vv.push_back({l,r});
}
dp[1]=1;
sum[1]=1;
for(int i=2;i<=n;i++)
{
for(int j=0;j<vv.size();j++)
{
int l=i-vv[j].second,r=i-vv[j].first;
l=max(l,0ll);
r=max(r,0ll);
dp[i]=(dp[i]+(sum[r]-sum[l]+dp[l])%mod)%mod;
}
sum[i]=(sum[i-1]+dp[i])%mod;
}
cout<<dp[n];
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _=1;
//cin>>_;
while(_--)
solve();
}
#include <bits/stdc++.h>
#define int long long
//#pragma GCC optimize(2)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
const int mod=998244353;
vector<pair<int,int> >vv;
int dp[maxn];
int tree[maxn*4];
int lazy[maxn*4];
void init()
{
vv.clear();
}
void build(int l,int r,int t) {
lazy[t] = 0;
tree[t]=0;
if (l == r)tree[t] = dp[l];
else{
int mid=(l+r)>>1;
build(l,mid,t<<1);
build(mid+1,r,t<<1|1);
}
}
void pushdown(int t)
{
if(lazy[t]==0)return ;
lazy[t<<1]+=lazy[t];
lazy[t<<1]%=mod;
lazy[t<<1|1]+=lazy[t];
lazy[t<<1|1]%=mod;
tree[t<<1]+=lazy[t];
tree[t<<1]%=mod;
tree[t<<1|1]+=lazy[t];
tree[t<<1|1]%=mod;
lazy[t]=0;
}
void update(int l,int r,int t,int L,int R,int d)
{
if(L>r||R<l)
return ;
if(l>=L&&r<=R)
{
tree[t]+=d;
tree[t]%=mod;
lazy[t]+=d;
lazy[t]%=mod;
}
else
{
pushdown(t);
int mid=(l+r)>>1;
if(mid>=L)
update(l,mid,t<<1,L,R,d);
if(mid<R)
update(mid+1,r,t<<1|1,L,R,d);
}
}
int query(int l,int r,int t,int L,int R)
{
if(l>=L&&r<=R)return tree[t];
if(l>R||r<L)return 0;
int mid=(l+r)>>1;
pushdown(t);
if(mid>=L)
return query(l,mid,t<<1,L,R);
if(mid<R)
return query(mid+1,r,t<<1|1,L,R);
}
void solve()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=k;i++)
{
int l,r;
cin>>l>>r;
vv.push_back({l,r});
}
dp[1]=1;
update(1,n,1,1,1,1);
for(int i=1;i<=n;i++)
{
for(int j=0;j<vv.size();j++)
{
pair<int,int> xx=vv[j];
if(i!=1)
dp[i]=query(1,n,1,i,i)%mod;
if(dp[i]!=0)
update(1,n,1,i+xx.first,i+xx.second,dp[i]);
}
}
cout<<dp[n];
}
signed main() {
int _=1;
while(_--) {
init();
solve();
}
return 0;
}
E
题意
ai+1=ai*ai%m
给你一个初始值是x ,然后余数是m的值,然后让你求前N项的和
#include <bits/stdc++.h>
#define int long long
//#pragma GCC optimize(2)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
map<int,int>mm;
const int maxn=1e5+5;
int dp[maxn]={0};
void solve()
{
mm.clear();
int N,x,m;
cin>>N>>x>>m;
int cnt=x;
mm[cnt]=1;
dp[1]=cnt;
int i=2;
int l,r;
while(1)
{
cnt=(cnt*cnt)%m;
if(cnt==0)
{
cout<<dp[i-1];
return;
}
if(cnt==1)
{
cout<<dp[i-1]+N-(i-1);
return ;
}
if(mm[cnt]==0)
{
dp[i]=dp[i-1]+cnt;
mm[cnt]=i;
i++;
}
else
{
l=mm[cnt];
r=i;
break;
}
}
int res=dp[l-1];
int yy=dp[r-1]-dp[l-1];
int xx=r-l;
N-=l-1;
int shang=N/xx;
res+=shang*yy;
int yv=N%xx;
res+=dp[l-1+yv]-dp[l-1];
cout<<res;
}
signed main() {
int _=1;
while(_--) {
solve();
}
return 0;
}
F
思路其实很简单,但是碰到区间更新会T
很显然用线段树更新
#include <bits/stdc++.h>
#define int long long
//#pragma GCC optimize(2)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int inf=1e9+5;
const int maxn=2e5+5;
int n,q;
int di[maxn*4],ri[maxn*4],lazydi[maxn*4],lazyri[maxn*4];
void build(int xx)
{
for(int i=1;i<maxn*4;i++)
{
di[i]=xx;
ri[i]=xx;
lazydi[i]=xx;
lazyri[i]=xx;
}
}
void pushdowndi(int t)
{
lazydi[t<<1]=min(lazydi[t<<1],lazydi[t]);
lazydi[t<<1|1]=min(lazydi[t<<1|1],lazydi[t]);
di[t<<1]=min(di[t<<1],lazydi[t<<1]);
di[t<<1|1]=min(di[t<<1|1],lazydi[t<<1|1]);
}
void updatedi(int l,int r,int t,int L,int R,int d)
{
if(l>R||r<L)
return;
if(l>=L&&r<=R)
{
lazydi[t]=min(lazydi[t],d);
di[t]=min(lazydi[t],di[t]);
}
else
{
pushdowndi(t);
int mid=(l+r)>>1;
if(mid>=L)
updatedi(l,mid,t<<1,L,R,d);
if(mid<R)
updatedi(mid+1,r,t<<1|1,L,R,d);
}
}
int querydi(int l,int r,int t,int L,int R)
{
if(l>=L&&r<=R)
return di[t];
if(l>R||r<L)
return inf;
int mid=(l+r)>>1;
pushdowndi(t);
if(mid>=L)
return querydi(l,mid,t<<1,L,R);
if(mid<R)
return querydi(mid+1,r,t<<1|1,L,R);
}
void pushdownri(int t)
{
lazyri[t<<1]=min(lazyri[t<<1],lazyri[t]);
lazyri[t<<1|1]=min(lazyri[t<<1|1],lazyri[t]);
ri[t<<1]=min(ri[t<<1],lazyri[t<<1]);
ri[t<<1|1]=min(ri[t<<1|1],lazyri[t<<1|1]);
}
void updateri(int l,int r,int t,int L,int R,int d)
{
if(l>R||r<L)
return;
if(l>=L&&r<=R)
{
lazyri[t]=min(lazyri[t],d);
ri[t]=min(lazyri[t],ri[t]);
}
else
{
pushdownri(t);
int mid=(l+r)>>1;
if(mid>=L)
updateri(l,mid,t<<1,L,R,d);
if(mid<R)
updateri(mid+1,r,t<<1|1,L,R,d);
}
}
int queryri(int l,int r,int t,int L,int R)
{
if(l>=L&&r<=R)
return ri[t];
if(l>R||r<L)
return inf;
int mid=(l+r)>>1;
pushdownri(t);
if(mid>=L)
return queryri(l,mid,t<<1,L,R);
if(mid<R)
return queryri(mid+1,r,t<<1|1,L,R);
}
void solve()
{
cin>>n>>q;
int sum=(n-2)*(n-2);
build(n);
for(int i=1;i<=q;i++)
{
int op,x;
cin>>op>>x;
if(op==1)
{
int d=querydi(1,n,1,x,x);
sum-=(d-2);
updateri(1,n,1,2,d-1,x);
}
else
{
int r=queryri(1,n,1,x,x);
sum-=(r-2);
updatedi(1,n,1,2,r-1,x);
}
}
cout<<sum;
}
signed main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _=1;
while(_--) {
solve();
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
int n,x,y,q,op,k,r[N],c[N];
int main(){
cin>>n>>q;
x=y=n;
ll ans=(n-2LL)*(n-2LL);
while(q--){
cin>>op>>k;
if(op==1) {
if (k < y) {
ans -= x - 2;
while (y > k) c[y--] = x - 2;
} else ans -= c[k];
}else{
if (k < x) {
ans -= y - 2;
while (x > k) r[x--] = y - 2;
} else ans -= r[k];
}
}
cout<<ans;
return 0;
}