T1.破解D-H协议

传送门

这个题就是BSGS的板子题……

然后这里补充一点嘛,就是第二重循环的枚举范围。我们是在枚举\(a^{tm-y}\),把tm换成i,这个的最大值就是\(i - (m - 1) < c\),即\(i < c + m - 1\)

#include<bits/stdc++.h>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n') using namespace std;
typedef long long ll;
const int M = 200005;
const int mod = 999979; int read()
{
int ans = 0,op = 1;char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') ans *= 10,ans += ch - '0',ch = getchar();
return ans * op;
} int g,P,n,A,B; struct Hash
{
int sta[M],top,head[M<<3],ecnt,num[M],val[M],nxt[M];
void init(){ecnt = 0;while(top) head[sta[top--]] = 0;}
void insert(int x,int y)
{
int h = x % mod;
for(int i = head[h];i;i = nxt[i]) if(num[i] == x) {val[i] = y;return;}
if(!head[h]) sta[++top] = h;
nxt[++ecnt] = head[h],head[h] = ecnt;
num[ecnt] = x,val[ecnt] = y;
}
int query(int x)
{
int h = x % mod;
for(int i = head[h];i;i = nxt[i]) if(num[i] == x) return val[i];
return -1;
}
}H; int mul(int a,int b,int t){return 1ll * a * b % t;}
int qpow(int a,int b,int t)
{
int p = 1;
while(b)
{
if(b & 1) p = mul(p,a,t);
a = mul(a,a,t),b >>= 1;
}
return p;
}
int gcd(int a,int b){return b ? gcd(b,a%b) : a;}
int exgcd(int a,int b,int &x,int &y)
{
if(!b){x = 1,y = 0;return a;}
int d = exgcd(b,a%b,y,x);
y -= a / b * x;
return d;
} int inv(int a,int b)
{
int x,y;
exgcd(a,b,x,y);
return (x % b + b) % b;
} int BSGS(int a,int b,int c)
{
int cnt = 0,G,d = 1;
while((G = gcd(a,c)) != 1)
{
if(b % G) return -1;
cnt++,b /= G,c /= G,d = mul(d,a/G,c);
}
b = mul(b,inv(d,c),c);
H.init();
int s = sqrt(c),p = 1;
rep(i,0,s-1)
{
if(p == b) return i + cnt;
H.insert(mul(p,b,c),i),p = mul(p,a,c);
}
int q = p,t;
for(int i = s;i <= c + s - 2;i += s)
{
t = H.query(q);
if(t != -1) return i - t + cnt;
q = mul(q,p,c);
}
return -1;
} int main()
{
g = read(),P = read(),n = read();
rep(i,1,n)
{
A = read(),B = read();
int a = BSGS(g,A,P);
int b = BSGS(g,B,P);
printf("%d\n",qpow(g,mul(a,b,P-1),P));
}
return 0;
}

T2.社交网络

传送门

这个题是有向图有根树生成树计数,根必须为1.

其实和无向图的生成树计数基本是一样的……就是这次的基尔霍夫矩阵按照有向图来建造。

然后因为根是1,所以我们把矩阵的第一行和第一列删掉,剩下的用高斯消元就可以了。

#include<bits/stdc++.h>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n') using namespace std;
typedef long long ll;
const int M = 255;
const int mod = 1e4+7; int read()
{
int ans = 0,op = 1;char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') ans *= 10,ans += ch - '0',ch = getchar();
return ans * op;
} int n,m,x,y,f[M][M];
int inc(int a,int b){return (a + b) % mod;}
int mul(int a,int b){return 1ll * a * b % mod;}
int qpow(int a,int b)
{
int p = 1;
while(b)
{
if(b & 1) p = mul(p,a);
a = mul(a,a),b >>= 1;
}
return p;
} int gauss()
{
int ans = 1;
rep(i,2,n)
{
rep(j,i+1,n) if(f[j][i]) {swap(f[j],f[i]),ans = mod - ans;break;}
if(!f[i][i]) return 0;
ans = mul(ans,f[i][i]);
int inv = qpow(f[i][i],mod-2);
rep(j,i+1,n)
{
int cur = mul(f[j][i],inv);
rep(k,i,n) f[j][k] = inc(f[j][k],mod - mul(f[i][k],cur));
}
}
return ans;
} int main()
{
n = read(),m = read();
rep(i,1,m) x = read(),y = read(),f[x][x]++,f[x][y]--;
printf("%d\n",gauss());
return 0;
}

T3.交错序列

传送门

个人认为是最难的一道了……

\(x^ay^b\)难以处理,于是我们转化为\((n-y)^ay^b\),那么展开以后就是\(\sum_{i=0}^a(-1)^{a-i}n^iC_a^iy^{a+b-i}\)

于是我们只要求出\(y^i\)的和就可以了。我们可以考虑DP。

用\(dp[i][j][0/1]\)表示当前选取到长度为i,当前位为0/1,当前序列中1的个数的j次方之和。

然后对于0/1变0的情况是没有什么变化的,就是\(dp[i][j][0] += dp[i-1][j][0/1]\)

如果这一位是1的话,根据二项式定理就可以得到\(dp[i][j][1] += \sum_{k=0}^jC_j^kdp[i-1][k][0]\)

于是这个可以用矩阵乘法优化。然后我写完之后还被卡常了……把矩乘内部开成ll,最内一层循环不取模就过了……

最后就按照上面的式子计算答案。

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n') using namespace std;
typedef long long ll;
const int M = 200005;
const int N = 185;
const int mod = 999979; int read()
{
int ans = 0,op = 1;char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') ans *= 10,ans += ch - '0',ch = getchar();
return ans * op;
} int n,a,b,m,siz,C[N][N],ans;
int inc(int a,int b){return (a + b) % m;}
int mul(int a,int b){return 1ll * a * b % m;} struct matrix
{
ll f[N][N];
matrix(){memset(f,0,sizeof(f));}
void init(){rep(i,0,siz-1) f[i][i] = 1;}
friend matrix operator * (const matrix &a,const matrix &b)
{
matrix c;
rep(i,0,siz-1)
rep(j,0,siz-1)
{
rep(k,0,siz-1) c.f[i][j] += a.f[i][k] * b.f[k][j];
c.f[i][j] %= m;
}
return c;
}
friend matrix operator ^ (matrix a,int b)
{
matrix p;
p.init();
while(b)
{
if(b & 1) p = p * a;
a = a * a,b >>= 1;
}
return p;
}
}G; int main()
{
n = read(),a = read(),b = read(),m = read(),siz = (a+b+1) << 1;
C[0][0] = 1;
rep(i,1,a+b)
{
C[i][0] = 1;
rep(j,1,i) C[i][j] = inc(C[i-1][j-1],C[i-1][j]);
}
rep(i,0,a+b)
{
G.f[i][i] = G.f[i][i+a+b+1] = 1;
rep(j,0,i) G.f[i+a+b+1][j] = C[i][j];
}
G = G ^ n;
int cur = 1;
rep(i,0,a)
{
int now = ((a - i) & 1) ? -1 : 1;
ans = inc(ans,mul(mul(cur,C[a][i]),mul(now,inc(G.f[a+b-i][0],G.f[siz-1-i][0]))));
cur = mul(cur,n);
}
printf("%d\n",(ans % m + m) % m);
return 0;
}

T4.解锁屏幕

传送门

这题挺好玩啊。

但是可以显而易见的看出是状压DP。然后转移也很好想……

\(dp[i][j]\)表示选取集合i,末尾为j的方案数。转移的时候枚举点,按照题中条件判断即可。然后注意在两点连线上的点需要预处理。

然后注意答案要连四个及以上的点,模数是1e8+7。其实很奇怪这玩意复杂度最坏是\(2^nn^2\)的,但是就是过了……

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n') using namespace std;
typedef long long ll;
const int M = 1000005;
const int mod = 1e8+7; int read()
{
int ans = 0,op = 1;char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') ans *= 10,ans += ch - '0',ch = getchar();
return ans * op;
} struct dot
{
double x,y;
}a[25]; int n,G[25][25],dp[1<<20][21],ans;
int inc(int a,int b){return (a+b) % mod;}
double slope(const int &f,const int &g) {return (a[g].y - a[f].y) / (a[g].x - a[f].x);}
bool in(int i,int j,int k)
{
if((a[k].y >= a[i].y && a[k].y <= a[j].y) || (a[k].y >= a[j].y && a[k].y <= a[i].y))
{
if((a[k].x >= a[i].x && a[k].x <= a[j].x) || (a[k].x >= a[j].x && a[k].x <= a[i].x)) return 1;
}
return 0;
} int count(int x)
{
int cur = 0;
while(x) cur += x & 1,x >>= 1;
return cur;
} int main()
{
n = read();
rep(i,0,n-1) scanf("%lf%lf",&a[i].x,&a[i].y),dp[1<<i][i] = 1;
rep(i,0,n-1)
rep(j,0,n-1)
rep(k,0,n-1)
{
if(k == i || k == j) continue;
if(in(i,j,k))
{
//printf("%d %d %d\n",i,j,k);
if(a[k].x == a[i].x && a[k].x == a[j].x) G[i][j] |= (1<<k);
else if(slope(i,j) == slope(k,j)) G[i][j] |= (1<<k);
}
}
//rep(i,0,n-1)
//{rep(j,0,n-1) printf("$%d ",G[i][j]);enter;}
rep(i,1,(1<<n)-1)
{
rep(j,0,n-1)
{
if(!(i & (1 << j))) continue;
rep(k,0,n-1)
{
if(i & (1<<k)) continue;
if((i & G[j][k]) != G[j][k]) continue;
dp[i | (1<<k)][k] = inc(dp[i][j],dp[i | (1<<k)][k]);
}
}
}
//rep(i,1,(1<<n)-1)
//{rep(j,0,n-1) printf("#%d ",dp[i][j]);enter;}
rep(i,1,(1<<n)-1)
{
if(count(i) < 4) continue;
rep(j,0,n-1) if(i & (1 << j)) ans = inc(ans,dp[i][j]);
}
printf("%d\n",ans);
return 0;
}

T5.九连环

传送门

听说这题在数学书上有……?还是必修五?

emm可能是A版……? 反正我的B版上没有TAT。

然后通过爆搜通过百度知道,答案就是\(\lfloor\frac{2^n+1}{3}\rfloor\)

然后就写一下FFT就能过…… 不过我太懒了 我用了python。 代码没有。

T6.异或序列

这个以前写过。看这里

最新文章

  1. 记录我的点点滴滴从此刻做起——iOS开发工程师
  2. SQL 常用的命令 (转)
  3. 图文详解Unity3D中Material的Tiling和Offset是怎么回事
  4. 【代码笔记】iOS-抽屉效果的实现
  5. Android 开源项目
  6. CSS+HTML网页设计与布局(学习笔记1)
  7. PHP集成支付宝快速实现充值功能
  8. 【转】MAC使用adb工具
  9. PHP中计算时间差(上周,上月,去年,昨天等)
  10. 操作PDF文档功能的相关开源项目探索——iTextSharp 和PDFBox
  11. 程序设计实践C++ 程序代写(QQ 928900200)
  12. C#基础1:Console类
  13. 10分钟精通SharePoint - SharePoint拓扑结构
  14. 十一、Spring Boot 集成Shiro和CAS
  15. Linux 系统调用过程详细分析
  16. python基础4--控制流
  17. 20165223 week6测试错题总结
  18. react 路由导航栏 withRouter
  19. MongoDB查询结果存放入新的Collection
  20. 在linux下,去除^M,将windows格式文件(dos文件)改为unix格式文件

热门文章

  1. 【BZOJ3316】JC loves Mkk 分数规划+单调队列
  2. 页游手游服务器(五)sql缓存层
  3. 蓝屏代码stop:0X000000EA(0X85E286B8,0X8635F210,0XF7A53CBC,0X00000001)
  4. VOFM 例程
  5. 3.15课&#183;&#183;&#183;&#183;&#183;&#183;&#183;&#183;&#183;out传值(传址)
  6. java搭建 SpringMVC+Mybatis(SMM)+mybatis-generate
  7. GDI+在绘制验证码中的使用
  8. Java多线程系列 JUC锁06 Condition条件
  9. 大话设计模式--原型模式 Prototype -- C++实现
  10. 使用jQuery为博客生成目录