22noip10连 day10
水仙花
考虑正难则反,把 两个至少满足一个 变为 两个都不满足
我们发现反着想有一条十分优美的性质,那就是最长的不合法序列是 O(logm)O(\log m)O(logm) 级别的。那么意味着预处理 sis_isi (长度为 iii 的不合法序列的方案数)的时间复杂度是 O(mlog2m)O(m \log^2m)O(mlog2m) 。
然后容斥,数列中的数可重复
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,p=998244353;
int n,m,s[20],f[N],g[20][N];
int main()
{
cin>>n>>m;s[1]=m;
for(int i=1;i<=m;i++)g[1][i]=1;
for(int i=2;i<=17;i++)
for(int j=1;j<=m;j++){
for(int k=2*j;k<=m;k+=j)g[i][k]=(g[i][k]+g[i-1][j])%p;
s[i]=(s[i]+g[i][j])%p;
}
f[0]=1;
for(int i=0;i<n;i++)
for(int j=1;j<=min(n-i,17);j++)
f[i+j]=(f[i+j]+1ll*(j&1?1:-1)*f[i]*s[j]%p)%p;
cout<<(f[n]+p)%p;
return 0;
}
22noip10连 day9
激光
通过排序确定上下或者左右关系,重新开一个数组记录这个关系,查找是否有空位的手法简洁
#include<bits/stdc++.h>
#define N 200005
using namespace std;
int T,n,m,k,b[N][4];
char s[5];
struct node{int x,y,tp,id;}a[N];
bool cmp1(const node &p,const node &q){return p.x<q.x||p.x==q.x&&p.y<q.y;}
bool cmp2(const node &p,const node &q){return p.y<q.y||p.y==q.y&&p.x<q.x;}
bool cmp3(const node &p,const node &q){return p.id<q.id;}
void solve(){
stable_sort(a+1,a+k+1,cmp1);
for(int i=1;i<k;i++)if(a[i].x==a[i+1].x){
if(a[i].tp==1)b[a[i+1].id][0]=0;
if(a[i+1].tp==0)b[a[i].id][1]=0;
}
stable_sort(a+1,a+k+1,cmp2);
for(int i=1;i<k;i++)if(a[i].y==a[i+1].y){
if(a[i].tp==3)b[a[i+1].id][2]=0;
if(a[i+1].tp==2)b[a[i].id][3]=0;
}
stable_sort(a+1,a+k+1,cmp3);
int cnt=0,ff=0;
for(int i=1;i<=k;i++)if(!b[i][a[i].tp]){
if((++cnt)>=3){puts("No");return;}
int flag=0;
for(int t=0;t<4;t++)flag|=b[i][t];
ff|=flag;
}
if(ff||!cnt)puts("Yes");
else puts("No");
}
int main(){
cin>>T;
while(T--){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++){
scanf("%d%d%s",&a[i].x,&a[i].y,s),a[i].id=i;
if(s[0]=='L')a[i].tp=0;
if(s[0]=='R')a[i].tp=1;
if(s[0]=='U')a[i].tp=2;
if(s[0]=='D')a[i].tp=3;
for(int t=0;t<4;t++)b[i][t]=1;
}
solve();
}
return 0;
}


被折叠的 条评论
为什么被折叠?



