原题 LG-P4005 小 Y 和地铁。
找一下性质,发现对于只有一个交点的站点一定无贡献,对于有且仅有两个交点的考虑发现其有效状态只有四种(即发现对于从线段的左端点与右端点绕过是等效的),于是考虑随机一个初始状态后
原题 SP422 TRANSP2 - Transposing is Even More Fun。
双倍经验 SP419 TRANSP - Transposing is Fun。
挺长时间以前写的题解:
一道很好的群论题,尤其是其中转化的思想还是很高妙的。
不难发现,我们考虑按序为矩阵标号,从
这个东西朴素的交换次数是
由题面中
于是我们想到,若将二进制数抽象为长度为
这时就存在一个很人类智慧的转化,我们可以容易想到每
用经典的莫反思想推导:
可以通过精细实现达到
加强版:
有点不太理解这道题的意义,完全就是更卡常一点,需要更加精细实现,本质没有任何变化。。
推导部分完全相同,最终式子:
发现对于 dfs 跑一下,同时处理
Upd:一种新的思路:
考虑将二进制数抽象为长度为
考虑套用一下 Polya,对于旋转
然后进行一些转化:
接下来的步骤则与之前相同。
原题 LOJ #6672. 「XXOI 2019」惠和惠惠和惠惠惠。
大概是我目前做过所有题里最有意思的了。(推逝式子多有意思)
puts("0") 的。
问题可抽象为在平面直角坐标系中从
考虑 DP,设状态
显然有:
对于
令默慈金数为
从圆上画弦很好理解,从本题理解略有困难,大概是钦定一个从
以上似乎就是个
容易发现其生成函数为:
解个一元二次方程将
继续考虑用
此时对于
再往下就有各种各样的做法了,这里简单提几个并丢一下链接。
首先直接
对于一个
还可以考虑通过某些方式获取结论发现
然后是一些可能用到的资料:
LOJ #6672. 「XXOI 2019」惠和惠惠和惠惠惠(生成函数,整式递推)
xxxxxxxxxx144123
4567891011
12using namespace std;13
14mt19937 rnd(random_device{}());15int rndd(int l, int r){return rnd() % (r - l + 1) + l;}16bool rnddd(int x){return rndd(1, 100) <= x;}17
18typedef unsigned int uint;19typedef unsigned long long unll;20typedef long long ll;21typedef long double ld;22
2324
25template < typename T = int >26inline T read(void);27
28int N;29int pos[50];30int status[50];31bool itsc[50][50];32int cur(0);33int ans(INT_MAX);34struct Line{int l, r;};35basic_string < Line > lines;36
37int main(){38 freopen("corruption.in", "r", stdin);39 freopen("corruption.out", "w", stdout);40 auto notIntersect = [](int a, int b)->bool{41 if(line(a).l > line(b).l)swap(a, b);42 switch(status[a]){43 case 1:{44 switch(status[b]){45 case 1: return line(a).r < line(b).l || line(b).r < line(a).r;46 case 2: return true;47 case 3: return line(b).l > line(a).r;48 case 4: return line(b).r > line(a).r;49 }break;50 }51 case 2:{52 switch(status[b]){53 case 1: return true;54 case 2: return line(a).r < line(b).l || line(b).r < line(a).r;55 case 3: return line(b).r > line(a).r;56 case 4: return line(b).l > line(a).r;57 }break;58 }59 case 3:{60 switch(status[b]){61 case 1: return true;62 case 2: return line(b).r < line(a).r || line(b).l > line(a).r;63 case 3: return line(b).r > line(a).r;64 case 4: return line(b).l > line(a).r;65 }break;66 }67 case 4:{68 switch(status[b]){69 case 1: return line(b).r < line(a).r || line(b).l > line(a).r;70 case 2: return true;71 case 3: return line(b).l > line(a).r;72 case 4: return line(b).r > line(a).r;73 }break;74 }75 }return false;76 };77 auto Intersect = [notIntersect](int i, int j)->bool{return !notIntersect(i, j);};//判断写反了,懒的改就写了个 notIntersect 转一下。。。。。。78 auto SetOrigin = [Intersect](void)->void{79 cur = 0;80 for(int i = 1; i <= N; ++i)for(int j = i + 1; j <= N; ++j)cur += (itsc[i][j] = itsc[j][i] = Intersect(i, j));//, printf("checking i = %d, j = %d, res = %d\n", i, j, itsc[i][j] ? 1 : 0);81 ans = min(ans, cur);82 };83 auto Anneal = [Intersect](void)->void{84 double T = 50.0, delta = 0.993;85 while(T > 1e-2){86 int idx = rndd(1, N);87 int val = rndd(1, 4);88 while(val == status[idx])val = rndd(1, 4);89 int nxt = cur;90 int lsts = status[idx]; status[idx] = val;91 for(int i = 1; i <= N; ++i)if(i != idx){92 if(itsc[idx][i] && !Intersect(idx, i))--nxt;93 else if(!itsc[idx][i] && Intersect(idx, i))++nxt;94 }95 if(nxt < cur || exp(-(double)(nxt - cur) / T) > (double)rndd(1, 114514) / 114514){96 cur = nxt;97 ans = min(ans, cur);98 for(int i = 1; i <= N; ++i)if(i != idx)itsc[idx][i] = itsc[i][idx] = Intersect(idx, i);99 }else status[idx] = lsts;100 T *= delta;101 }102 };103 int T = read();104 while(T--){105 memset(pos, 0, sizeof pos);106 memset(status, 0, sizeof status);107 lines.clear();108 ans = INT_MAX;109 N = read();110 for(int i = 1; i <= N; ++i){111 int val = read();112 if(pos[val])lines += Line{min(pos[val], i), max(pos[val], i)};113 else pos[val] = i;114 }N = lines.size();115 if(!N){printf("0\n"); continue;}116 int t = 30;117 while(t--){118 memset(itsc, 0, sizeof itsc);119 for(int i = 1; i <= N; ++i)status[i] = rndd(1, 4);120 // for(int i = 1; i <= N; ++i)printf("%d ", status[i]);121 // printf("\n");122 SetOrigin();123 Anneal();124 }printf("%d\n", ans);125 }126 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);127 return 0;128}129
130template < typename T >131inline T read(void){132 T ret(0);133 int flag(1);134 char c = getchar();135 while(c != '-' && !isdigit(c))c = getchar();136 if(c == '-')flag = -1, c = getchar();137 while(isdigit(c)){138 ret *= 10;139 ret += int(c - '0');140 c = getchar();141 }142 ret *= flag;143 return ret;144}xxxxxxxxxx104123
4567891011
12using namespace std;13
14mt19937 rnd(random_device{}());15int rndd(int l, int r){return rnd() % (r - l + 1) + l;}16bool rnddd(int x){return rndd(1, 100) <= x;}17
18typedef unsigned int uint;19typedef unsigned long long unll;20typedef long long ll;21typedef long double ld;22
232425
26template < typename T = int >27inline T read(void);28
29int A, B;30int N, gcdv;31ll ans(0);32ll pow2[LIMIT + 100];33basic_string < int > Prime;34bitset < LIMIT + 100 > notPrime;35struct Num{int v; int cnt;};36basic_string < Num > fact;37
38ll qpow(ll a, ll b){39 ll ret(1), mul(a);40 while(b){41 if(b & 1)ret = ret * mul % MOD;42 b >>= 1;43 mul = mul * mul % MOD;44 }return ret;45}46void Init(int x){47 fact.clear();48 for(auto p : Prime){49 if(p * p > x)break;50 if(x % p == 0)fact += {p, 0};51 while(x % p == 0)fact.back().cnt++, x /= p;52 }if(x != 1)fact += {x, 1};53}54void dfs(int dep = 0, ll d = 1, ll base = 1, ll div = 1){55 if(dep == (int)fact.size())56 return (ans += pow2[gcdv * (N / d)] * (d / div * base) % MOD) %= MOD, void();57 dfs(dep + 1, d, base, div);58 base *= (fact.at(dep).v - 1), div *= fact.at(dep).v;59 for(int i = 1; i <= fact.at(dep).cnt; ++i)60 d *= fact.at(dep).v, dfs(dep + 1, d, base, div);61}62
63int main(){64 freopen("transposition.in", "r", stdin);65 freopen("transposition.out", "w", stdout);66 for(int i = 2; i <= LIMIT; ++i){67 if(!notPrime[i])Prime += i;68 for(auto p : Prime){69 if(p * i > LIMIT)break;70 notPrime[p * i] = true;71 if(i % p == 0)break;72 }73 }74 pow2[0] = 1;75 for(int i = 1; i <= LIMIT; ++i)pow2[i] = pow2[i - 1] * 2 % MOD;76 int T = read();77 while(T--){78 A = read(), B = read();79 N = (A + B) / __gcd(A, B), gcdv = __gcd(A, B);80 Init(N);81 ans = 0;82 dfs();83 (ans *= qpow(N, MOD - 2)) %= MOD;84 printf("%lld\n", (pow2[A + B] - ans + MOD) % MOD);85 }86 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);87 return 0;88}89
90template < typename T >91inline T read(void){92 T ret(0);93 int flag(1);94 char c = getchar();95 while(c != '-' && !isdigit(c))c = getchar();96 if(c == '-')flag = -1, c = getchar();97 while(isdigit(c)){98 ret *= 10;99 ret += int(c - '0');100 c = getchar();101 }102 ret *= flag;103 return ret;104}xxxxxxxxxx66123
4567891011
12using namespace std;13
14mt19937 rnd(random_device{}());15int rndd(int l, int r){return rnd() % (r - l + 1) + l;}16bool rnddd(int x){return rndd(1, 100) <= x;}17
18typedef unsigned int uint;19typedef unsigned long long unll;20typedef long long ll;21typedef long double ld;22
23template < typename T = int >24inline T read(void);25
26int N, K;27ll MOD;28ll dp[11000000];29ll inv[11000000];30
31int main(){32 freopen("slack_off.in", "r", stdin);33 freopen("slack_off.out", "w", stdout);34 N = read(), K = read(), MOD = read();35 if(K > N)printf("0\n"), exit(0);36 inv[1] = 1;37 for(int i = 2; i <= N + 100; ++i)inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;38 dp[0] = 1;39 dp[1] = K - 1;40 dp[2] = (ll)K * (K - 1) / 2 % MOD;41 for(int i = 0; i + 3 <= N - K + 1; ++i)42 dp[i + 3] = (43 dp[i] * 3 * i % MOD * (i + 1) % MOD +44 dp[i + 1] * ((5 * i + 3 * K + 6) % MOD) % MOD * (i + 1) % MOD +45 dp[i + 2] * (i + K + 1) % MOD * (i + K + 2) % MOD46 ) % MOD * inv[i + 3] % MOD * inv[i + K + 2] % MOD;47 printf("%lld\n", dp[N - K + 1]);48 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);49 return 0;50}51
52template < typename T >53inline T read(void){54 T ret(0);55 int flag(1);56 char c = getchar();57 while(c != '-' && !isdigit(c))c = getchar();58 if(c == '-')flag = -1, c = getchar();59 while(isdigit(c)){60 ret *= 10;61 ret += int(c - '0');62 c = getchar();63 }64 ret *= flag;65 return ret;66}