Skip to content

泉州一中信息学Blog

信息学奥赛技术分享博客

  • 登录
  • 小学oj
  • 中学oj
  • 测试页面1
  • Toggle search form

DAY*

Posted on 2024年7月19日 By 陈, 禹恩 DAY*无评论

唯一一次提早下班

T1:蓝题,但黄题(有人没文件读写)

//100pts
#include<bits/stdc++.h>
using namespace std;
long long T,n,m,ak,ans[10005][7],cnt,xl[5],yl[5],flag=0;
char a[105][105];
void work(int xa,int ya,int xb,int yb,int xc,int yc) {
    ak++;
    ans[ak][1]=xa,ans[ak][2]=ya,ans[ak][3]=xb,ans[ak][4]=yb,ans[ak][5]=xc,ans[ak][6]=yc;
    if(a[xa][ya]==&#039;0&#039;) a[xa][ya]=&#039;1&#039;;
    else a[xa][ya]=&#039;0&#039;;
    if(a[xb][yb]==&#039;0&#039;) a[xb][yb]=&#039;1&#039;;
    else a[xb][yb]=&#039;0&#039;;
    if(a[xc][yc]==&#039;0&#039;) a[xc][yc]=&#039;1&#039;;
    else a[xc][yc]=&#039;0&#039;;
}
void op(int x,int y)
{
    if(x==n-1&&y==m-1)
    {
        work(x,y,x+1,y,x,y+1);
        work(x,y,x+1,y,x+1,y+1);
        work(x,y,x,y+1,x+1,y+1);
        return ;
    }
    if(x==n-1&&y==m)
    {
        work(x,y,x,y-1,x+1,y);
        work(x,y,x,y-1,x+1,y-1);
        work(x,y,x+1,y,x+1,y-1);
        return ;
    }
    if(x==n&&y==m-1)
    {
        work(x,y,x-1,y,x,y+1);
        work(x,y,x-1,y,x-1,y+1);
        work(x,y,x,y+1,x-1,y+1);
        return ;
    }
    if(x==n&&y==m)
    {
        work(x,y,x-1,y,x,y-1);
        work(x,y,x-1,y,x-1,y-1);
        work(x,y,x,y-1,x-1,y-1);
        return ;
    }
}
int main() {
    freopen("bulb.in","r",stdin);
    freopen("bulb.out","w",stdout);
    cin>>T;
    while(T--) {
        ak=0;
        scanf("%lld%lld",&n,&m);
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=m; j++) {
                cin>>a[i][j];
            }
        }
        for(int i=1; i<=n-2; i++) {
            for(int j=1; j<=m; j++) {
                if(a[i][j]==&#039;0&#039;) continue;
                if(a[i][j]==&#039;1&#039;) {
                    if(j!=m) {
                        if(a[i][j+1]!=&#039;1&#039;) work(i,j,i+1,j,i+1,j+1);
                        else work(i,j,i,j+1,i+1,j);
                    } else work(i,j,i+1,j,i+1,j-1);
                }
            }
        }

        for(int j=1; j<=m-2; j++) {
            for(int i=n-1; i<=n; i++) {
                if(a[i][j]==&#039;0&#039;) continue;
                if(a[i][j]==&#039;1&#039;) {
                    if(i==n-1)
                    {
                        if(a[i+1][j]==&#039;1&#039;) work(i,j,i+1,j,i,j+1);
                        else work(i,j,i,j+1,i+1,j+1);
                    }
                    else work(i,j,i,j+1,i-1,j+1);
                }
            }
        }
        cnt=0;
        for(int i=n-1;i<=n;i++)
        {
            for(int j=m-1;j<=m;j++)
            {
                if(a[i][j]==&#039;1&#039;) 
                {
                    cnt++;
                    xl[cnt]=i;
                    yl[cnt]=j;
                }
            }
        }
        if(cnt==3)
        {
            work(xl[1],yl[1],xl[2],yl[2],xl[3],yl[3]);
        }
        flag=0;
        if(cnt==2)
        {
            for(int i=n-1;i<=n;i++)
            {
                for(int j=m-1;j<=m;j++)
                {
                    if(a[i][j]==&#039;0&#039;) 
                    {
                        work(xl[1],yl[1],xl[2],yl[2],i,j);
                        op(i,j);
                        flag=1;
                        break;
                    }
                }
                if(flag==1) break;
            }
        }
        if(cnt==1)
        {
            op(xl[1],yl[1]);
        }
        if(cnt==4)
        {
            work(xl[1],yl[1],xl[2],yl[2],xl[3],yl[3]);
            op(xl[4],yl[4]);
        }
        printf("%lld\n",ak);
        for(int i=1;i<=ak;i++)
        {
            for(int j=1;j<=6;j++) printf("%lld ",ans[i][j]);
            cout<<endl;
        }
    }
    return 0;
}

T2:

n<=1e5,但k很少

考虑将n映射到k上,则可以状压解决(可以发现答案不会更优)

考虑随机,答案对应的k个值映射到不同的k的概率为“k!/k^k”约为24/256

多随机几次就好了

#include<bits/stdc++.h>
using namespace std;
long long st;
int n,k,id[10005],uu,vv,ans=114514,tt[10005],sum,num,step=75,kl[10005],v;
int dp[10001][32];
vector<int> G[10005];
mt19937 rd(time(0));
void dfs(int x,int f) {
    for(int i=0;i<G[x].size();i++)
    {
        if(G[x][i]!=f) dfs(G[x][i],x);
    }
    for(int i=1;i<st;i++) dp[x][i]=114514;
//  dp[x][0]=1;
    dp[x][1<<(kl[x]-1)]=1;
    for(int i=0;i<G[x].size();i++)
    {
        v=G[x][i];
        if(v!=f)
        {
            for(int j=0;j<st;j++)
            {
                for(int h=0;h<st;h++)
                {
                    dp[x][j|h]=min(dp[x][j|h],dp[x][j]+dp[v][h]);
                }
            }
            ans=min(ans,dp[x][st-1]);
        }

    }
    return ;
}
int main() {
    freopen("insect.in","r",stdin);
    freopen("insect.out","w",stdout);
    cin>>n>>k;
    for(int i=1; i<=n; i++) {
        scanf("%d",&id[i]);
    }
    for(int i=1; i<=n-1; i++) {
        scanf("%d%d",&uu,&vv);
        G[uu].push_back(vv);
        G[vv].push_back(uu);
    }
    st=1<<k;

    while(step--)
    {
        for(int i=1;i<=n;i++)
        {
            tt[i]=(rd()%k+k)%k+1;
        }
        for(int i=1;i<=n;i++)
        {
            kl[i]=tt[id[i]];
        }
        dfs(1,0);
    }
    cout<<ans;
    return 0;
}

T3

发现一定有解,又发现如果有一个点跟两个以上讨厌的点在同一个集合,则另一集合讨厌的最多一个

则交换当前点位置一定更优

交换完再遍历考虑有关联的点

//30pts
#include<bits/stdc++.h>
using namespace std;
long long n,m,aa,bb,st,flag,cnt,f[300005];
vector<int> G[300005];
void work(int x)
{
    cnt=0;
    for(int i=0;i<G[x].size();i++) if(f[x]==f[G[x][i]]) cnt++;
    if(cnt>=2)
    {
        f[x]=f[x]^1;
        for(int i=0;i<G[x].size();i++) work(G[x][i]);
    }
}
int main() {
//  freopen("horse.in","r",stdin);
//  freopen("horse.out","w",stdout);
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        scanf("%lld%lld",&aa,&bb);
        G[aa].push_back(bb);
        G[bb].push_back(aa);
    }
    for(int i=1;i<=n;i++)
    {
        work(i);
    }
    for(int i=1;i<=n;i++) cout<<f[i];
    return 0;
}

T4

容斥,都能想到,ans=sigma(0~n)(f[i]jc[n-i](-1)^i)

(选定碰到i个障碍,剩下随便选)

考虑如何计算f[i](碰到i个障碍的方案数)

将每一个a[i]和b[i]的值连边,则图必定为一些环加一些链

则方案为一个端点只能属于一条边的方案数

考虑将每两个点中间加一个点,就转化为点匹配

n个点匹配k个,相当于从n个点中取出k个,不能相邻

则答案为C(n-k,k)

再来考虑环,若不选(1,n),则答案跟链一样;选(1,n),则转化为剩下链选k-1个

答案为C(n-k,k)+C(n-2-(k-1)=n-k-1,k-1)

单独处理完后背包合并就好了,把每一个环的不同数量的贡献拆开,共n个(共n个点),容量为n

“`cpp
</h3>

#include
using namespace std;
const long long mod=1e9+7;
int op=1,vv;
long long hf[3005][3005],f[3005][3005];
long long n,a[3005],b[3005],st,ans,jc[6005],ny[6005],fl=-1,ls,id,cnt,vis[3005],flag,hsum[3005],u[6005],v[6005],head[3005],nex[6005];
void add(int xx,int yy) {
op++;
u[op]=xx,v[op]=yy;
nex[op]=head[u[op]];
head[u[op]]=op;
}
long long ksm(long long aa,long long bb ) {
ls=1;
while(bb>0) {
if(bb%2<span class="text-highlighted-inline" style="background-color: #fffd38;">1) {
ls=(ls<em>aa)%mod;
}
bb/=2;
aa=(aa</em>aa)%mod;
}
return ls;
}
void dfs(int x,int ed) {
vis[x]=cnt;
for(int i=head[x]; i!=0; i=nex[i]) {
if(vis[v[i]]</span>0) {
dfs(v[i],i);
hsum[cnt]++;
} else {
if(vis[v[i]]!=0&&i!=(ed^1)&&v[i]!=x) {
flag=1;
return ;
}
}
}
}
long long C(int aa,int bb) {
if(bb<span class="text-highlighted-inline" style="background-color: #fffd38;">0) return 1;
if(aa<bb) return 0;
else return ((jc[aa]<em>ny[aa-bb]%mod)</em>ny[bb]%mod)%mod;
}
void work() {</span>

<pre><code>cnt=0;
for(int i=1; i<=n; i++) {
if(vis[i]==0) {
flag=0;

cnt++;
hsum[cnt]=1;
vis[i]=cnt;
dfs(i,0);
hf[cnt][0]=1;
// cout<<flag<<endl;
if(flag==0) {
for(int j=1; j<=hsum[cnt]; j++) {
hf[cnt][j]=C(2*hsum[cnt]-j,j);
hf[cnt][j]%=mod;
}
} else {
for(int j=1; j<=hsum[cnt]; j++) {
hf[cnt][j]=C(2*hsum[cnt]-j,j)+C(2*hsum[cnt]-j-1,j-1);
hf[cnt][j]%=mod;
}
}
}
}
</code></pre>

// for(int i=1;i<=cnt;i++)
// {
// cout<<i<<": "<<hsum[i]<<endl;;
// for(int j=1;j<=hsum[i];j++) cout<<" "<<hf[i][j]<<" ";
// cout<<endl;
// }
f[0][0]=1;
for(int i=1; i=1; h–) {
f[i][h]=f[i-1][h];
for(int j=hsum[i]; j>=1; j–) {
if(h>=j) {
f[i][h]+=f[i-1][h-j]*hf[i][j];
f[i][h]%=mod;
}
}
}
}

}
int main() {
// freopen("game.in","r",stdin);
// freopen("game.out","w",stdout);
cin>>n;
for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
for(int i=1; i<=n; i++) scanf("%lld",&b[i]);
for(int i=1; i<=n; i++) {
add(a[i],b[i]);
add(b[i],a[i]);
}
jc[0]=1;
for(int i=1; i=1; i–) ny[i]=(ny[i+1]<em>(i+1))%mod;
ny[0]=1;
work();
fl=1;
// for(int i=0;i<=n;i++)
// {
// cout<<f[cnt][i]<<endl;
// }
for(int i=0; i<=n; i++) {
ans=(ans+mod+(fl</em>(f[cnt][i]%mod*jc[n-i]%mod))%mod)%mod;
fl=-fl;
}
cout<<ans;
return 0;
}

“`n^n

训练日志

文章导航

Previous Post: 暑假聚龙外国语学校集训Day-3
Next Post: CSP-S 集训Day4

发表回复 取消回复

要发表评论,您必须先登录。

2025年 6月
一 二 三 四 五 六 日
 1
2345678
9101112131415
16171819202122
23242526272829
30  
« 2月    

2024常州 Class Classic OI Problems Contest cqr的长乐集训2023 CZYZ LOC New Game NOI NOIP Password Protected PM_PK Preview Problems Retrospect Selfmade Qusetion STL The end Training Uneasy Problem 蒟蒻 通报

  • 训练日志
  • 链表
  • 入门
  • 模拟
  • dfs序
  • 并查集
  • spfa
  • 最小割
  • 矩阵树定理
  • 仙人掌
  • BSGS
  • 凸包
  • 回文自动机
  • 递推与动归
  • 堆
  • 莫队算法
  • ST表
  • Treap
  • 树套树
  • 可持久化线段树
  • 初赛
  • 搜索
  • 贪心
  • 深度优先搜索
  • 欧拉图
  • dijkstra
  • 费用流
  • 哈夫曼树
  • kruskual
  • 置换
  • 旋转卡壳
  • KMP
  • 区间动归
  • STL
  • 链表
  • 可并堆
  • sply
  • 主席树
  • 可持久化字典树
  • 算法
  • 动态规划
  • 构造
  • 广度优先搜索
  • 最短路
  • floyd
  • 最大流
  • 虚树
  • prim
  • 筛法
  • 半平面交
  • 字典树
  • 背包动归
  • 基础数据结构
  • 分块
  • 线段树
  • 替罪羊树
  • K-DTree
  • 图论
  • 二分法
  • 迭代搜索
  • 拓扑排序
  • 有上下界网络流
  • 生成树
  • 快速幂
  • 后缀数组
  • 树形动归
  • 哈希表
  • 中级数据结构
  • 平衡树
  • 可持久化数据结构
  • 数据结构
  • 三分法
  • 启发式搜索
  • 图的连通
  • 点分治
  • 博弈论
  • AC自动机
  • 状压动归
  • 单调栈
  • 树状数组
  • 高级数据结构
  • OI资料
  • 数学
  • 高精度
  • 差分约束
  • 树上倍增
  • 素数测试
  • 后缀自动机
  • 数位动归
  • 单调队列
  • 新闻
  • 几何
  • 随机化
  • 二分图染色
  • 树链剖分
  • 欧拉函数
  • manacher
  • 斜率优化
  • 离线处理
  • 信息学奥赛学长风采
  • 字符串
  • 二分图匹配
  • prufer编码
  • 卡特兰数
  • 密码学
  • 决策单调
  • 赛后总结
  • 其他
  • 2-SAT
  • 最近公共祖先
  • 矩阵乘法
  • 记忆化搜索
  • 网络流
  • Link cut tree
  • 排列组合
  • 树
  • 高斯消元
  • 乘法逆元
  • 容斥原理
  • 调和级数
  • 概率与期望
  • 模线性方程组
  • 莫比乌斯反演
  • 快速傅里叶变换
  • 扩展欧几里德
  • 最大公约数与最小公倍数

近期文章

  • DP杂题
  • 2025年2月13日模拟赛
  • HLOJ-TEST ROUND 4-T1/T2(构造)- 3
  • HLOJ-TEST ROUND 4-T1/T2(构造)- 2
  • HLOJ-TEST ROUND 4-T1/T2(构造)- 1

近期评论

归档

  • 2025年2月
  • 2025年1月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月

Copyright © 2025 泉州一中信息学Blog.

Powered by PressBook WordPress theme