T1
将每一个单词中的各个字母的数量统计出来,然后可以得到一个表示字母数量的数列,将它哈希一下即可
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int read()
{
int a = 0,x = 1;char ch = getchar();
while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
return a*x;
}
const int hash1 = 131,hash2 = 133,P1 = 1000429,P2 = 20190631;
const int N=2e6+7;
int n;
int t[26];
ll sum = 0;
char s[107];
int val[N];
int head[N],go[N],nxt[N],cnt;
void add(int u,int v)
{
go[++cnt] = v;
nxt[cnt] = head[u];
head[u] = cnt;
val[cnt] = 1;
}
int main()
{
freopen("anagram.in","r",stdin);
freopen("anagram.out","w",stdout);
n = read();
for(int i = 1;i <= n;i ++) {
scanf("%s",s);
for(int j = strlen(s)-1;~j;j --) {
t[s[j]-'a'] ++;
}
int tmp1=0,tmp2=0;
for(int j = 0;j < 26;j ++) {
tmp1 = (1ll*tmp1*hash1 + t[j])%P1;
tmp2 = (1ll*tmp2*hash2 + t[j])%P2;
t[j] = 0;
}
bool flag = 0;
for(int e = head[tmp1];e;e = nxt[e]) {
int v = go[e];
if(v == tmp2) {
flag = 1;
printf("%lld
",sum += (val[e]++));
break;
}
}
if(!flag) {add(tmp1,tmp2);printf("%lld
",sum);}
}
return 0;
}
T2
使用 BFS 预处理各个点之间的间距,然后枚举计算。玄学信仰下过掉 1000
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int read()
{
int a = 0,x = 1;char ch = getchar();
while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
return a*x;
}
const int N=1e3+7;
int dis[N][N];
int n;
int head[N],go[N<<1],nxt[N<<1],cnt;
void add(int u,int v)
{
go[++cnt] = v;
nxt[cnt] = head[u];
head[u] = cnt;
}
void dfs(int u,int fa,int* f)
{
if(fa) f[u] = f[fa]+1;
for(int e = head[u];e;e = nxt[e]) {
int v = go[e];
if(v == fa) continue;
dfs(v,u,f);
}
}
long long ans = 0;
int main()
{
freopen("dist.in","r",stdin);
freopen("dist.out","w",stdout);
n = read();
for(int i = 1;i < n;i ++) {
int u = read(),v = read();
add(u,v);add(v,u);
}
for(int i = 1;i <= n;i ++) {
dfs(i,0,dis[i]);
}
for(int i = 1;i <= n;i ++) {
for(int j = i+1;j <= n;j ++) {
for(int k = j+1;k <= n;k ++) {
ans += min(dis[i][j],min(dis[i][k],dis[j][k]));
}
}
}
printf("%lld",ans);
return 0;
}
T3
对于 (m leq 100) 使用 DP ,并使用矩阵快速幂进行加速
对于 (m+1) 是 2 的整数幂,计算得出每种或和的方案数。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
int read()
{
int a = 0,x = 1;char ch = getchar();
while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
return a*x;
}
const int N=1e6+7,P=998244353;
int n,m,p;
int calc(int s)
{
int ret = 0;
while(s) s -= s&-s,ret ++;
return ret;
}
int fpow(int a,int x,int q)
{
if(x == 0) return 1;
if(x == 1) return a%q;
int t = fpow(a,x/2,q);
if(x&1) return t*t%q*a%q;
else return t*t%q;
}
void MOD(int &a)
{
if(a>=P) a -= (a/P)*P;
}
struct node{
int n,m;
int a[520][520];
void clear() {n = m = 0;memset(a,0,sizeof(a));}
friend node operator * (node a,node b)
{
node ret;
ret.clear();
// printf("! !
");
ret.m = a.m,ret.n = b.n;
for(int i = 0;i <= ret.n;i ++) {
for(int j = 0;j <= ret.m;j ++) {
for(int k = 0;k <= a.n;k ++) {
MOD(ret.a[i][j] += a.a[k][j]*b.a[i][k]);
}
}
}
// printf("^_^
");
return ret;
}
};
node qpow(node a,int x)
{
node tmp = a,ret = a;
x --;
while(x){
if(x&1) ret = ret*tmp;
tmp = tmp*tmp;
x >>= 1;
// printf("%lld
",x);
}
return ret;
}
int f[35];
void subtask()
{
int ans = 0;
int qwq = fpow(2,n,P)-1;
f[0] = 1;
for(int i = 1;i <= 30;i ++) MOD(f[i] = f[i-1]*qwq);
for(int i = 0;i <= m;i ++) {
int len = calc(i);
MOD(ans += f[len]*fpow(p,i,P));
// printf("%d %d
",i,fpow((fpow(2,n,P)-1),len,P));
}
printf("%lld",ans);
}
signed main()
{
freopen("or.in","r",stdin);
freopen("or.out","w",stdout);
n = read(),m = read(),p = read();
if((m&(m+1)) == 0) {subtask();return 0;}
node b;b.clear();
int M=0;
while(M<m) M = M<<1|1;
b.n = b.m = M;
for(int i = 0;i <= M;i ++) {
for(int j = 0;j <= m;j ++) {
b.a[i|j][i] ++;
}
}
// b.print();
node I = qpow(b,n);
node a;a.clear();
a.n = m,a.m = 0;
a.a[0][0] = 1;
int ans = 0,qwq = 1;
for(int i = 0;i <= M;i ++) {
MOD(ans += qwq*I.a[i][0]);
MOD(qwq *= p);
}
printf("%lld",ans);
return 0;
}
T4
直接爆搜
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1e6+7;
int p[N],vis[N];
int n,t[N];
void check()
{
for(int i = 1;i <= n;i ++) {
if(p[p[i]] != i) return;
}
int tmp = 0;
for(int i = 1;i <= n;i ++) {
for(int j = 1+i;j <= n;j ++) {
if(p[j] < p[i]) tmp ++;
}
}
t[tmp] ++;
}
void dfs(int s)
{
if(s == n+1) {check();return;}
for(int i = 1;i <= n;i ++) {
if(vis[i]) continue;
if(i < s) {
if(p[i] != s) continue;
}
p[s] = i;vis[i] = 1;
dfs(s+1);vis[i] = 0;
}
}
int read()
{
int a = 0,x = 1;char ch = getchar();
while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
return a*x;
}
int k;
int main()
{
freopen("perm.in","r",stdin);
freopen("perm.out","w",stdout);
n = read(),k = read();
dfs(1);
for(int i = 0;i < k;i ++) printf("%d",t[i]%2);
return 0;
}