17-09-13模拟赛

T1:可以发现,满足题设条件的方案只有三个位置成一行或是三个位置成直角。

记录每一行与列白色方格的个数,由此求得红色方格的个数。

对于成行或成列的情况,分别求出中间是红色或白色的情况的方案个数。

对于成直角的情况,则枚举直角顶点,计算其对应行与对应列的方案个数。

注意答案可能会超过long long范围。

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define ll long long
 5 #define mod 1000000000000000000
 6 #define MN 4000005
 7 #define row(x) (sum[x])
 8 #define col(x) (sum[x+n])
 9 using namespace std;
10 inline int in(){
11     int x=0;bool f=0; char c;
12     for (;(c=getchar())<‘0‘||c>‘9‘;f=c==‘-‘);
13     for (x=c-‘0‘;(c=getchar())>=‘0‘&&c<=‘9‘;x=(x<<3)+(x<<1)+c-‘0‘);
14     return f?-x:x;
15 }
16 struct exll{
17     ll a[2];
18 }ans;
19 ll sum[MN];
20 inline exll operator +(const exll &x,const ll &y){
21     exll z;memset(z.a,0,sizeof(z.a));
22     z.a[1]=x.a[1]+y;z.a[0]=x.a[0]+(z.a[1]/mod);z.a[1]%=mod;return z;
23 }
24 char s[MN];
25 int n,m;
26 int main()
27 {
28     n=in();m=in();memset(ans.a,0,sizeof(ans.a));
29     for (int i=0;i<n;++i){
30         scanf("%s",s+i*m);for (int j=0;j<m;++j)
31         row(i)+=1ll*(s[i*m+j]-‘0‘),col(j)+=1ll*(s[i*m+j]-‘0‘);
32     }for (int i=0;i<n;++i)ans=ans+1ll*(row(i)*(m-row(i))*(m-row(i)-1)),ans=ans+1ll*(row(i)*(row(i)-1)*(m-row(i)));
33     for (int i=0;i<m;++i) ans=ans+1ll*(col(i)*(n-col(i))*(n-col(i)-1)),ans=ans+1ll*(col(i)*(col(i)-1)*(n-col(i)));
34     for (int i=0;i<n;++i)
35     for (int j=0;j<m;++j){
36         if (s[i*m+j]==‘1‘) ans=ans+2ll*((m-row(i))*(n-col(j)));
37         else ans=ans+2ll*(row(i)*col(j));
38     }if (ans.a[0]) printf("%lld%018lld",ans.a[0],ans.a[1]);
39     else printf("%lld",ans.a[1]);return 0;
40 }

T2:可以发现,对对一个数取φ会使该数的值以极快的速率下降。

对一个大于1的奇数取φ,结果一定是偶数;对一个偶数取φ,结果一定小等于该数的一半;φ(1)=1.

所以一个数最多取log级别次φ就能变为1.

考虑用欧拉筛O(值域)求φ,而后用线段树维护序列的区间最大值和区间乘积。

每次修改定位到一个区间后,如果该区间内最大值超过1,则继续往下递归,否则不用直接返回上一级;

或者直到递归到长度为1的区间后,直接将该值取φ即可。修改的复杂度最多为O(n log n).

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define ll long long
 5 #define L (x<<1)
 6 #define R (x<<1|1)
 7 #define mid ((l+r)>>1)
 8 #define mod 1000000007
 9 #define MN 200005
10 #define MV 10000005
11 using namespace std;
12 inline int in(){
13     int x=0;bool f=0; char c;
14     for (;(c=getchar())<‘0‘||c>‘9‘;f=c==‘-‘);
15     for (x=c-‘0‘;(c=getchar())>=‘0‘&&c<=‘9‘;x=(x<<3)+(x<<1)+c-‘0‘);
16     return f?-x:x;
17 }
18 int mx[MN<<2],a[MN],phi[MV],pri[MV];
19 int n,m,tp,x,y,mn=0,cnt=0;
20 ll pro[MN<<2];
21 inline void getphi(int n){
22     phi[1]=1;for (int i=2;i<n;++i){
23         if (!phi[i]) pri[++cnt]=i,phi[i]=i-1;
24         for (int j=1;i*pri[j]<n&&j<=cnt;++j){
25             if (i%pri[j]) phi[i*pri[j]]=phi[i]*phi[pri[j]];
26             else {phi[i*pri[j]]=phi[i]*pri[j];break;}
27         }
28     }
29 }
30 inline void pushup(int x){
31     mx[x]=max(mx[L],mx[R]);pro[x]=1ll*pro[L]*pro[R]%mod;
32 }
33 inline void pushdown(int x,int l,int r){
34     if (mx[x]==1) return;
35     if (l==r) {mx[x]=pro[x]=phi[mx[x]];return;}
36     pushdown(L,l,mid);pushdown(R,mid+1,r);pushup(x);
37 }
38 inline void update(int x,int l,int r,int a,int b){
39     if (a<=l&&b>=r) {pushdown(x,l,r);return;}
40     if (a<=mid) update(L,l,mid,a,b);
41     if (b>mid) update(R,mid+1,r,a,b);pushup(x);
42 }
43 inline ll query(int x,int l,int r,int a,int b){
44     if (a<=l&&b>=r) return pro[x];
45     if (b<=mid) return query(L,l,mid,a,b);
46     else if (a>mid) return query(R,mid+1,r,a,b);
47     else return 1ll*query(L,l,mid,a,mid)*query(R,mid+1,r,mid+1,b)%mod;
48 }
49 inline void build(int x,int l,int r){
50     if (l==r){mx[x]=pro[x]=a[l];return;}
51     build(L,l,mid);build(R,mid+1,r);pushup(x);
52 }
53 int main()
54 {
55     n=in();m=in();for (int i=1;i<=n;++i)
56     a[i]=in(),mn=max(mn,a[i]);getphi(mn+1);build(1,1,n);
57     for (int i=1;i<=m;++i){
58         tp=in();x=in();y=in();
59         if (tp==1) update(1,1,n,x,y);
60         else printf("%lld\n",query(1,1,n,x,y));
61     }return 0;
62 }

T3:最大权闭合子图,即二分图匹配。

观察到质数除了2以外都是奇数,所以起冲突的两个数奇偶性必定不同,所以将奇数分为一边,偶数分为一边。

又因为构成2两数之和的只有1+1,又因为乘以1对答案没有影响,所以读入时可以舍弃1的情况。

建图时对每个数取对数,变为求和最大。

S向每个奇数连边权为log(权值)的边,每个偶数向T连边权为log(权值)的边,有冲突的点之间连边,边权为inf.

得出答案时,从S开始dfs,每次只走满流的边。

对于左边的点,如果能遍历到,那么把它加入答案;对于右边的点,如果不能遍历到,把它加入答案。

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<queue>
 6 #define ll long long
 7 #define ld long double
 8 #define MN 1000005
 9 #define MM 5005
10 #define mod 1000000007
11 #define inf 0x7fffffff
12 #define eps 1e-12
13 using namespace std;
14 inline int in(){
15     int x=0;bool f=0; char c;
16     for (;(c=getchar())<‘0‘||c>‘9‘;f=c==‘-‘);
17     for (x=c-‘0‘;(c=getchar())>=‘0‘&&c<=‘9‘;x=(x<<3)+(x<<1)+c-‘0‘);
18     return f?-x:x;
19 }
20 struct edge{
21     int to,next;
22     ld cap;
23 }e[MN<<1];
24 int head[MM],iter[MM],lev[MM],b[2][MM];
25 int cnt=1,s,t,n,x;
26 bool vis[MM],np[MN];
27 inline void ins(int x,int y,ld cp){
28     e[++cnt].to=y;e[cnt].next=head[x];head[x]=cnt;e[cnt].cap=cp;
29     e[++cnt].to=x;e[cnt].next=head[y];head[y]=cnt;e[cnt].cap=0;
30 }
31 inline void getp(int n){
32     np[1]=1;for (int i=2;i*i<n;++i)
33     if (!np[i]) for (int j=i;i*j<n;++j)np[i*j]=1;
34 }
35 inline void bfs(){
36     queue<int>q;memset(lev,-1,sizeof(lev));
37     lev[s]=0;q.push(s);
38     while (!q.empty()){
39         int u=q.front();q.pop();
40         for (int i=head[u];i;i=e[i].next){
41             int v=e[i].to;
42             if (e[i].cap>eps&&lev[v]==-1)
43             lev[v]=lev[u]+1,q.push(v);
44         }
45     }
46 }
47 inline ld dfs(int u,ld f){
48     if (u==t) return f;ld used=0.0;
49     for (int &i=iter[u];i;i=e[i].next){
50         int v=e[i].to;
51         if (e[i].cap>eps&&lev[u]+eps<lev[v]){
52             ld w=dfs(v,min(f-used,e[i].cap));
53             if (w>eps){
54                 e[i].cap-=w;e[i^1].cap+=w;used+=w;
55                 if (used==f) return f;
56             }
57         }
58     }return used;
59 }
60 inline void dinic(){
61     while (1){
62         bfs();if (lev[t]==-1) return;
63         memcpy(iter,head,sizeof(head));
64         ld d=0.0;while ((d=dfs(s,inf))>eps);
65     }
66 }
67 inline void dfs2(int u){
68     for (int i=head[u];i;i=e[i].next){
69         int v=e[i].to;
70         if (e[i].cap>eps&&!vis[v]) vis[v]=1,dfs2(v);
71     }
72 }
73 int main()
74 {
75     n=in();getp(MN+1);s=0;t=n+1;
76     for (int i=1;i<=n;++i){x=in();if (x==1) continue;b[x&1][++b[x&1][0]]=x;}
77     for (int i=1;i<=b[0][0];++i) ins(s,i,log2(b[0][i]));
78     for (int i=1;i<=b[1][0];++i) ins(i+b[0][0],t,log2(b[1][i]));
79     for (int i=1;i<=b[0][0];++i)
80     for (int j=1;j<=b[1][0];++j)
81     if (!np[b[0][i]+b[1][j]]) ins(i,j+b[0][0],inf);
82     dinic();vis[s]=1;dfs2(s);ll ans=1ll;
83     for (int i=1;i<=b[0][0];++i) if (vis[i]) ans=1ll*ans*b[0][i]%mod;
84     for (int i=1;i<=b[1][0];++i) if (!vis[i+b[0][0]]) ans=1ll*ans*b[1][i]%mod;
85     printf("%lld",ans);return 0;
86 }
时间: 2024-10-11 15:01:14

17-09-13模拟赛的相关文章

2017.9.17校内noip模拟赛解题报告

预计分数:100+60+60=220 实际分数:100+60+40=200 除了暴力什么都不会的我..... T1 2017.9.17巧克力棒(chocolate) 巧克力棒(chocolate)Time Limit:1000ms Memory Limit:64MB题目描述LYK 找到了一根巧克力棒,但是这根巧克力棒太长了,LYK 无法一口吞进去.具体地,这根巧克力棒长为 n,它想将这根巧克力棒折成 n 段长为 1 的巧克力棒,然后慢慢享用.它打算每次将一根长为 k 的巧克力棒折成两段长为 a

2017/9/13模拟赛

粉饰(decorate) [题目描述] 小D有一块被分为n*m个格子的矩形鱼片.为了装饰鱼片,小D决定给每个格子上色.由于小D很喜欢红白,所以小D给每个格子涂上了红色或白色,第i行第j列的格子颜色记为c[i,j].涂完之后,小D想评估这块鱼片的"XY值".我们定义一个有序无重复三元格子组{(x1,y1),(x2,y2),(x3,y3)}为"XY组"当且仅当: |(x1-x2)*(y1-y2)|+|(x3-x2)*(y3-y2)|=0   (c[x1,y1]-c[x2

9.13——模拟赛

T1 全排列 (permutation.cpp/c/pas)Description从 n 个不同元素中任取 m(m≤n)个元素,按照一定的顺序排列起来,叫做从 n个不同元素中取出 m 个元素的一个排列.当 m=n 时所有的排列情况叫全排列.你觉得 xxy 会问你全排列的个数吗?Xxy:这个问题能淹死你,我才不问呢.我要问的是求 n 的全排列中,先递增后递减.先递减后递增的全排列的个数.由于答案可能很大,对 p 取余Input输入包含多组测试数据每组测试数据一行两个整数 n,pOutput对于每组

2014.09.13 网络赛杂感

在参加这场网络赛之前,我还在为暑假刷的一百多道水题而洋洋自得. 直到我开始做题的时候,才回想起那最初支配我的恐惧(借用的进击的巨人的台词,这句有点恶搞了). 十道题,五个小时,我们几个人也就解决了两道题.第二道计算几何的那道题是我们一番讨论才A过去的,虽然我几乎没有做过计算几何这类的题目,公式都是自己先推的. 更虐心的是,出题人是与我同龄的CLJ. 这种被俯视的感觉完全抬不起头来,就如同蝼蚁一般. 今天有点冷,下了一天的雨.我们连比赛的机房都没有,几个人找了个自习室,连上校园网默默的打比赛. 还

9.13模拟赛

全排列 (permutation.cpp/c/pas)Description从 n 个不同元素中任取 m(m≤n)个元素,按照一定的顺序排列起来,叫做从 n个不同元素中取出 m 个元素的一个排列.当 m=n 时所有的排列情况叫全排列.你觉得 xxy 会问你全排列的个数吗?Xxy:这个问题能淹死你,我才不问呢.我要问的是求 n 的全排列中,先递增后递减.先递减后递增的全排列的个数.由于答案可能很大,对 p 取余Input输入包含多组测试数据每组测试数据一行两个整数 n,pOutput对于每组测试数

2014.12.13模拟赛【准考证号】

准考证号 128M 0.1s ticket.cpp escription 蒟蒻hzwer NOIP2014惨跪,他依稀记得他的准考证号是37,现在hzwer又将要面临一场比赛,他希望准考证号不出现37(连续),同时他又十分讨厌4,所以也希望4出现在准考证号中...现在他想知道在A和B之间有多少合法的准考证号 Input 包含两个整数,A B Output 一个整数. Sample Input [输入样例一]1 10[输入样例二]25 50 Sample Output [输出样例一]9[输出样例二

一、17.09.13

一. 计算机程序: 为了让计算机执行某些操作或解决某个问题而编写的一系列头绪指令的集合!!! 二.java的技术有三类 ①java SE(标准版) ②java EE(企业版) ③java ME(移动版) 三.开发java程序的三个步骤 1.编写. ①文件名必须与类名一致. ②java严格区分大小写. 2.编译. ①javac 文件名.java ②产生class后缀名的文件 3.运行 ①java 文件名 ②显示内容 代码解析:public class Demo{外框架public static v

NOIP模拟9.17(TYVJNOIP2017模拟赛D2)

曼德布洛特(Mandelbrot)集合 算法课W1·leetcode654.MaximumBinaryTree 官方文档PackageOverview软件包概述--几何内核类 glClearColor第四个参数有什么用? dxd奈犯材http://p.baidu.com/itopic/main/center?uid=00266162633962396665360ebc&59m6丶号斗yrci6b觅滓问http://p.baidu.com/itopic/main/center?uid=4ba761

8.13模拟赛 T2

题面 大意:10000组询问,每次查询Σ(0<=i<=n)中(i! 末尾0的个数为偶数的 i 的个数)(n<=100000) 0的个数也就是求5的因子数  但我只会打暴力,这里我参考了xumingyang大佬的做法,用了类数位DP的方法 首先把n转化为5进制  得到这样子的一个数 如 1231424,可知这个数为 5?6*1+5?5*2+5?4*3+5?3*1+5?2*4+5?1*2+5?0*4 f[i][0/1]表示到第i位设一个数有n位 , 原文地址:https://www.cnbl

2019模拟赛09场解题报告

目录 2019模拟赛09场解题报告 目录la~~ 题一:瞬间移动 题二:食物订购 题三:马蹄印 题四:景观美化 2019模拟赛09场解题报告 标签(空格分隔): 解题报告 Forever_chen 2019.8.20 目录la~~ 题一:瞬间移动 [题面] 有一天,暮光闪闪突然对如何将一个整数序列a1,a2,...,an排序为一个不下降序列起了兴趣.身为一只年轻独角兽的她,只能进行一种叫做"单元转换"(unit shift)的操作.换句话说,她可以将序列的最后一个元素移动到它的起始位置