T1
solution
把字符串排序后插入到Trie树中,前面出现过几次相同形式的字符串,答案就加上几
code
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int b=131,P=1000429,maxn = 7e4+10,maxm = 1e7+10;
int n,vis[maxm];
char a[maxn];
long long ans;
int trie[maxn][30],cnt;
int build(char *c){
int len = strlen(c+1),root = 0;
for (int i = 1;i <= len;i++){
int nxt = c[i]-'a';
if (!trie[root][nxt]) trie[root][nxt] = ++cnt;
root = trie[root][nxt];
}
vis[root]++;
return vis[root]-1;
}
int main(){
freopen("anagram.in","r",stdin);
freopen("anagram.out","w",stdout);
scanf ("%d",&n);
for (int i = 1;i <= n;i++){
scanf ("%s",a+1);
int len = strlen(a+1);sort(a+1,a+len+1);
ans += build(a);
printf("%d
",ans);
}
}
T2
solution
预处理出两两点之间的距离,跟(floyd)差不多,枚举中转点累加答案,水过80分
code
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
int read(){
int x = 1,a = 0;char ch = getchar();
while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
return x*a;
}
const int maxn = 1005;
int n;
struct node{
int to,nxt;
}ed[maxn];
int head[maxn],tot;
void add(int u,int to){
ed[++tot].to = to;
ed[tot].nxt = head[u];
head[u] = tot;
}
int dep[maxn],f[maxn][30],dis[maxn][maxn];
void dfs(int x,int fa){
dep[x] = dep[fa]+1;
for (int i = 1;i <= 22;i++) f[x][i] = f[f[x][i-1]][i-1];
for (int i = head[x];i;i = ed[i].nxt){
int to = ed[i].to;
if (to == fa) continue;
f[to][0] = x;
dfs(to,x);
}
}
int lca(int x,int y){
if (dep[x] > dep[y]) swap(x,y);
for (int i = 22;i >= 0;i--){
if (dep[f[y][i]] >= dep[x]) y = f[y][i];
}
if (x == y) return x;
for (int i = 22;i >= 0;i--){
if (f[x][i] != f[y][i]) x = f[x][i],y = f[y][i];
}
return f[x][0];
}
int main(){
freopen("dist.in","r",stdin);
freopen("dist.out","w",stdout);
n = read();
for (int i = 1;i <= n-1;i++){
int x = read(),y = read();
add(x,y),add(y,x);
}
dfs(1,0);
for (int i = 1;i <= n;i++){
for (int j = 1;j <= n;j++){
if (i == j) continue;
int tmp = lca(i,j);
dis[i][j] = dep[i]+dep[j]-2*dep[tmp];
}
}
int ans = 0;
for (int i = 1;i <= n;i++){
for (int j = 1;j <= n;j++){
for (int k = 1;k <= n;k++){
if (i == j||i == k||k == j) continue;
ans += min(dis[i][j],min(dis[i][k],dis[k][j]));
}
}
}
printf("%d
",ans/6);
return 0;
}
T3
20分dp:
状态:(dp_{i,j})表示(i)个数,或和为(j)的方案数
转移:(dp_{i,jmid k})+=(dp_{i-1,j})
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#define int long long
using namespace std;
int read(){
int x = 1,a = 0;char ch = getchar();
while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
return x*a;
}
const int maxn = 1e3+10,mod = 998244353;
int n,m,p;
int dp[maxn][maxn];
int qpow(int a,int k){
int res = 1;a = a%mod;
while (k){
if (k&1) res = res*a%mod;
a = a*a%mod;
k >>= 1;
}
return res;
}
int getnum(int x){
int res = 0;
while (x) res++,x -= x&(-x);
return res;
}
signed main(){
freopen("or.in","r",stdin);
freopen("or.our","w",stdout);
n = read(),m = read(),p = read();
if (n <= 100&&m <= 100){
for (int i = 0;i <= m;i++) dp[1][i] = 1;
for (int i = 2;i <= n;i++){
for (int j = 0;j < 2*m;j++){
for (int k = 0;k <= m;k++){
(dp[i][j|k] += dp[i-1][j])%=mod;
}
}
}
int ans = 0;
for (int i = 0;i < 2*m;i++){
if (dp[n][i]) (ans += qpow(p,i)*dp[n][i]%mod)%=mod;
}
printf("%lld
",ans);
return 0;
}
int ans = 0;
for (int i = 1;i <= m;i++){
int res = getnum(i);
int num = qpow((qpow(2,n)-1),res)%mod;
(ans += qpow(p,i)*num%mod) %= mod;
}
printf("%lld
",ans);
return 0;
}
T4
solution
dfs枚举全排列,看是否合法,合法再统计答案 10分
code
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
int read(){
int x = 1,a = 0;char ch = getchar();
while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
return x*a;
}
const int maxn = 100;
int n,k;
bool vis[maxn];
int a[maxn],sum[maxn],num[maxn];
void fix(int x,int k){
for (int i = x;i <= n;i+=i&(-i)) sum[i] += k;
}
int query(int x){
int res = 0;
for (int i = x;i >= 1;i-=i&(-i)) res += sum[i];
return res;
}
void dfs(int x){
if (x == n+1){
for (int i = 1;i <= n;i++){
if (a[a[i]] != i) return;
}
int ans = 0;
memset(sum,0,sizeof(sum));
for(int i = n;i >= 1;i--){
fix(a[i],1);
ans += query(a[i]-1);
}
num[ans]++;
}
for (int i = 1;i <= n;i++){
if (vis[i] == 0){
vis[i] = 1,a[x] = i;
dfs(x+1);
vis[i] = 0;
}
}
}
int main(){
freopen("perm.in","r",stdin);
freopen("perm.out","w",stdout);
n = read(),k = read();
dfs(1);
for (int i = 0;i <= k-1;i++) printf("%d",num[i]%2);
return 0;
}