A.Color the Simple Cycle(polya计数+字符串匹配)

此题的难点在于确定置换的个数,由a[i+k]=a[i], e[i+k]=e[i]联想到KMP。

于是把原串和原串扩大两倍的目标串进行字符串匹配就能求出具体的置换。

这里的算法可以使用hash或者kmp。

然后套polya公式就行了。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr))
#define REP(i, n) for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i))
#define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define MID(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define E(x) (1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x) printf("%lld\n", x)
#define Read() freopen("data.in", "r", stdin)
#define Write() freopen("data.out", "w", stdout); typedef long long LL;
const double eps = 1e-;
const double PI = acos(-1.0);
const int inf = 0x1F1F1F1F; using namespace std; const int N = ;
const int MOD = ; int n;
int pre[N];
bool vis[][N];
int v[N], e[N];
int vv[N<<], ee[N<<]; void get_next(int P[]) {
int i, j = -;
pre[] = -;
for(i = ; i < n; ++i) {
while(j > - && P[j+] != P[i]) j = pre[j];
if(P[j + ] == P[i]) ++j;
pre[i] = j;
}
} void kmp(int T[], int P[], int f) {
get_next(P);
int i, k;
for(k = -, i = ; i < (n<<); ++i) {
while(k > - && P[k+] != T[i]) k = pre[k];
if(P[k+] == T[i]) ++k;
if(k == n - ) {
vis[f][i - n + ] = true;
k = pre[k];
}
}
} LL Pow(LL a, int b) {
LL res = ;
while(b) {
if(b&) res = (res*a)%MOD;
a = (a*a)%MOD;
b >>= ;
}
return res;
} int exp_gcd(int a, int b, int& x, int& y) {
if(b == ) {
x = ; y = ;
return a;
}
int d = exp_gcd(b, a%b, y, x); // x1 = y2, y1 = x2;
y -= a/b*x; //y1 = x2 - (a/b)*y2
return d;
} int Inv(int c) {
int x, y;
exp_gcd(c, MOD, x, y);
return x < ? x + MOD : x;
} int gcd(int a, int b) {
return b == ? a : gcd(b, a%b);
} int main() {
//Read(); int T, c, cnt, i;
LL ans;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &c);
for(i = ; i < n; ++i) {scanf("%d", &v[i]); vv[i] = vv[i+n] = v[i];}
for(i = ; i < n; ++i) {scanf("%d", &e[i]); ee[i] = ee[i+n] = e[i];}
CL(vis, false);
kmp(vv, v, );
kmp(ee, e, );
ans = cnt = ; for(i = ; i <= n; ++i) {
if(vis[][i] && vis[][i]) {
ans += Pow(c, gcd(i, n));
ans %= MOD;
cnt++;
//cout << pow(c, gcd(i, n)) << " " << gcd(i, n) << endl;
}
}
ans = ans*Inv(cnt)%MOD;
cout << ans << endl;
}
return ;
}

B.Catch the Theves(平面图最小割转对偶图最短路)

BZOJ 狼抓兔子的简化版。

C.Cubic Maze(待填坑)

D.Dragon Ball(线段树和单调栈优化DP)

容易得到DP方程 dp[i]=dp[j]+max(val[j+1,i]) (pre[i]<=j<i).

复杂度为O(n^2logn) 需要优化。

方程右边的max()可以通过单调栈O(n)求出。复杂度O(n^2).

我们可以发现,假设此时扫到了k 对于单调栈里维护的两个连续的数 a[i]和a[j] (i>j) 那么max[[j+1,i], k]=a[i].

此时这些转移点的右边最大值部分都是一样的,那么我们只要求出这些转移点的dp部分最小值就行了。用一个线段树维护dp值,可以在logn的时间求出。

但是这样还是行不通,一个单调递减序列足以达到最坏复杂度。

可以再用一个线段树来维护min(dp[j]+max(...))。

复杂度O(nlogn).

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
#include<stack>
#include<list>
#include<iostream>
#include<map>
using namespace std;
#define inf 0x3f3f3f3f
#define Max 100100
int max(int a,int b)
{
return a>b?a:b;
}
int min(int a,int b)
{
return a<b?a:b;
}
int dp[Max],t,n,typ[Max],val[Max],rec,q[Max],lef[Max];
struct node
{
int l,r,minx;
int mid()
{
return (l+r)>>;
}
}T[*Max];
void build(int l,int r,int rt)
{
T[rt].l=l;T[rt].r=r;
T[rt].minx=;
if(l==r)
{
// T[rt].max=val[l];
return ;
} int mid=T[rt].mid();
build(l,mid,rt<<);
build(mid+,r,rt<<|); }
void modify(int l,int rt,int data)
{
if(T[rt].l==T[rt].r)
{
T[rt].minx=data;
return;
}
int mid=T[rt].mid();
if(l<=mid)
modify(l,rt<<,data);
else
modify(l,rt<<|,data);
T[rt].minx=min(T[rt<<].minx,T[rt<<|].minx);
}
void query(int l,int r,int rt)
{
if(T[rt].l==l&&T[rt].r==r)
{
rec=min(rec,T[rt].minx);
return;
}
int mid=T[rt].mid();
if(l>=mid+)
query(l,r,rt<<|);
else if(r<=mid)
query(l,r,rt<<);
else
{
query(l,mid,rt<<);
query(mid+,r,rt<<|);
}
}
int main()
{
int i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=;i<=n;i++)
{
scanf("%d",&typ[i]);
}
for(i=;i<=n;i++)
{
scanf("%d",&val[i]);
}
dp[]=;
int top=;int tail=;
build(,n,);
q[]=;
memset(lef,,sizeof(lef));
for(i=;i<=n;i++)
{
// int maxn=val[i];
while(tail>top+&&val[i]>val[q[tail-]])
tail--;
q[tail]=i;
tail++;
dp[i]=inf;
for(j=tail-;j>top&&q[j]>lef[typ[i]];j--)
{
rec=inf;
query(max(q[j-],lef[typ[i]]),q[j]-,);
// printf("a");
dp[i]=min(rec+val[q[j]],dp[i]);
}
modify(i,,dp[i]);
lef[typ[i]]=i;
// printf("i %d dp %d\n",i,dp[i]);
}
printf("%d\n",dp[n]);
}
}

E.Invade the Mars(最短路变形)

这是个具有保护节点的最短路。 每个节点必须在到达他的所有前置节点之后才能访问它。

考虑在 堆优化dijkstra 判断入堆条件时 多加几个判断就ok了

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF ((LL)<<)
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... struct Edge{int p, next, w;}edge[];
int head[N], cnt, num[N];
VI node[N];
bool vis[N];
LL dis[N], mark[N];
struct qnode{
int v; LL c;
qnode(int _v=,LL _c=):v(_v),c(_c){}
bool operator <(const qnode &r)const{return c>r.c;}
};
void init()
{
mem(head,); cnt=; mem(num,);
FO(i,,N) node[i].clear();
}
void add_edge(int u, int v, int w)
{
edge[cnt].p=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++;
}
void dij(int n, int start)
{
mem(vis,); mem(mark,);
FOR(i,,n) dis[i]=INF;
priority_queue<qnode>que;
while (!que.empty()) que.pop();
dis[start]=;
que.push(qnode(start,));
qnode tmp;
while (!que.empty()) {
tmp=que.top(); que.pop();
int u=tmp.v;
if (vis[u]) continue;
FO(i,,node[u].size()) {
int v=node[u][i];
--num[v];
if (num[v]==&&mark[v]) dis[v]=max(mark[v],dis[u]), que.push(qnode(v,dis[v]));
}
vis[u]=;
for (int i=head[u]; i; i=edge[i].next) {
int v=edge[i].p;
if (num[v]) {
if (!mark[v]) mark[v]=dis[u]+edge[i].w;
else mark[v]=min(mark[v],dis[u]+edge[i].w);
}
if (!num[v]&&!vis[v]&&dis[v]>dis[u]+edge[i].w) {
dis[v]=dis[u]+edge[i].w;
que.push(qnode(v,dis[v]));
}
}
}
}
int main ()
{
int T, n, m, u, v, w;
scanf("%d",&T);
while (T--) {
init();
scanf("%d%d",&n,&m);
while (m--) scanf("%d%d%d",&u,&v,&w), add_edge(u,v,w);
FOR(i,,n) {
scanf("%d",num+i);
FOR(j,,num[i]) scanf("%d",&u), node[u].pb(i);
}
dij(n,);
printf("%lld\n",dis[n]);
}
return ;
}

F.Necklace(离线+树状数组)

BZOJ HH的项链的变形。

G.Euclidean Algorithm(数论综合)

题目需要求sigma(lcm(i,n))-sigma(gcd(i,n))是否能被c整除。

结合欧拉函数和积性函数可以推出这两个式子,最后用大整数质因子分解算法可以算出答案。

#include <stdio.h>
#include <ctime>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
const int TIME = ;
long long factor[],fac_num[];
int count;
int cmp(const void *a,const void *b)
{
long long temp;
temp = *(long long*)a-*(long long *)b;
if(temp==)
return ;
else if(temp<)
return -;
else return ;
}
long long gcd(long long a,long long b)
{
if(b==) return a;
return gcd(b,a%b);
}
long long multi_mod(long long a,long long b,long long n)
{
long long res = ;
a%=n;
for(;b;b>>=)
{
if(b&)
res = (res+a)%n;
a<<=;
a%=n;
}
return res;
}
long long multi_exp(long long a,long long b,long long n)
{
long long res = ;
for(;b;b>>=)
{
if(b&)
res = multi_mod(res,a,n);
a = multi_mod(a,a,n);
}
return res;
}
bool witness(long long a,long long n)
{
long long m,x,y;
int i,j = ;
m = n-;
while(m%==)
{
j++;
m>>=;
}
x = multi_exp(a,m,n);
for(i = ;i<=j;i++)
{
y = multi_exp(x,,n);
if(y==&&x!=&&x!=n-)
return false;
x = y;
}
if(y!=)
return false;
return true;
}
bool Miller_Rabin(long long n,int times)
{
int i;
long long a;
if(n==)
return false;
if(n==)
return true;
if(n%==)
return false;
for(i = ;i<=times;i++)
{
a = rand()%(n-)+;
if(!witness(a,n))
return false;
}
return true;
}
long long pollard_rho(long long n)
{
long long i = , x = (long long)fabs(1.0*(rand() % (n - ))) + , y, k, d, c;
y = x, k = ;
do { c = (long long)fabs(1.0*(rand() % (n - ))) + ; } while (c == || c == );
do
{
i++;
d = gcd(n + y - x, n);
if (d != && d != n) return d;
if (i == k) y = x, k <<= ;
x = (multi_mod(x, x, n) + n - c) % n;
} while (y != x);
return n;
}
void get_factor(long long n)
{
long long temp;
if(n==)
return ;
if(Miller_Rabin(n,TIME)==true)
{
factor[count++] = n;
return ;
}
temp = n;
while(temp>=n)
temp = pollard_rho(temp);
get_factor(temp);
get_factor(n/temp);
}
int main()
{
long long n,c,temp1,temp2,temp3,keep;
int count1,i,count2,T;
srand(time(NULL));
scanf("%d",&T);
while(T--)
{
scanf("%I64d%I64d",&n,&c);
count = ;
get_factor(n);
qsort(factor,count,sizeof(factor[]),cmp);
count1 = ;
count2 = ;
for(i = ;i<count;i++)
{
if(factor[i]!=factor[i-])
{
factor[count1] = factor[i-];
fac_num[count1++] = count2;
count2 = ;
}
else
count2++;
}
factor[count1] = factor[count-];
fac_num[count1++] = count2;
temp1 = ;
for(i=;i<count1;i++)
{
temp3 = (fac_num[i]+)*multi_exp(factor[i],fac_num[i],c)-fac_num[i]*multi_exp(factor[i],fac_num[i]-,c);
temp3 = (temp3+c)%c;
temp1*=temp3;
temp1%=c;
}
temp2 = ;
for(i = ;i<count1;i++)
{
keep = (factor[i]+)**c;
temp3 = (multi_exp(factor[i],*fac_num[i]+,keep)+)%keep/(factor[i]+);
temp2*=temp3;
temp2%=*c;
}
temp3 = (temp2-+*c)%(*c);
temp2 = ((((n%(*c))*temp3)%(*c)/)+n%c)%c;
temp3 = (temp2-temp1+c)%c;
if(temp3==)
printf("yes\n");
else
printf("no\n");
}
return ;
}

H.A pupil’s problem(水题)

韦达定理。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... int main ()
{
int T;
LL a, b, c;
scanf("%d",&T);
while (T--) {
scanf("%lld%lld%lld",&a,&b,&c);
LL delta=b*b-*a*c;
if (delta<) puts("NO");
else if (delta==) printf("%.2f\n",-(double)b//a);
else {
double m=sqrt(delta), x1=(-b-m)//a, x2=(-b+m)//a;
if (x1>x2) swap(x1,x2);
printf("%.2f %.2f\n",x1,x2);
}
}
return ;
}

I.Special sort(水题)

结构体排序。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... typedef struct{LL a, b, id, sum, eq;}Node;
Node node[N]; bool comp(Node a, Node b)
{
if (a.sum!=b.sum) return a.sum>b.sum;
if (a.eq!=b.eq) return a.eq>b.eq;
return a.id<b.id;
}
int main ()
{
int T, n;
scanf("%d",&T);
while (T--) {
scanf("%d",&n);
FOR(i,,n) {
scanf("%lld%lld",&node[i].a,&node[i].b);
node[i].id=i; node[i].sum=node[i].a+node[i].b;
if (node[i].a>node[i].b) node[i].eq=;
else if (node[i].a==node[i].b) node[i].eq=;
else node[i].eq=;
}
sort(node+,node+n+,comp);
FOR(i,,n) {
printf("%lld+%lld=[",node[i].a,node[i].b);
if (node[i].eq==) putchar('<');
else if (node[i].eq==) putchar('=');
else putchar('>');
printf("%lld]\n",node[i].sum);
}
puts("");
}
return ;
}

J.X Property(待填坑)

2011 Multi-University Training Contest 4 - Host by SDU的更多相关文章

  1. 2011 Multi-University Training Contest 1 - Host by HNU

    A.A + B problem(待填坑) B.Cat VS Dog(二分图匹配) 喜欢cat和喜欢dog的人构成了二分图,如果两个人有冲突则连一条边,则问题转化为二分图最大点独立集问题.ans=n-最 ...

  2. 2011 Multi-University Training Contest 8 - Host by HUST

    Rank:56/147. 开场看B,是个线段树区间合并,花了2hour敲完代码...再花了30min查错..发现push_down有问题.改了就AC了. 然后发现A过了很多人.推了个公式,发现是个分段 ...

  3. 2011 Multi-University Training Contest 7 - Host by ECNU

    AC: F I. rank 40/88. 开场看了F发现是个简单的DP,随便写了一下WA,,,发现把样例倒着输就过不了了...原来是忘了最后的时候开始上课的话可能上不了多久... 想到一个简洁的状态方 ...

  4. 2011 Multi-University Training Contest 6 - Host by JLU

    打了4hours,做出一道题...太菜了.rank:45/107 开场看B,题目看不懂...3hours半才发现i<=N-1,不是i<=x-1.然而还是不会. 看到J有人过了,发现是个简单 ...

  5. 2015 UESTC Winter Training #8【The 2011 Rocky Mountain Regional Contest】

    2015 UESTC Winter Training #8 The 2011 Rocky Mountain Regional Contest Regionals 2011 >> North ...

  6. HDU4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)

    Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. HDU 2018 Multi-University Training Contest 3 Problem A. Ascending Rating 【单调队列优化】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6319 Problem A. Ascending Rating Time Limit: 10000/500 ...

  8. 2015 Multi-University Training Contest 8 hdu 5390 tree

    tree Time Limit: 8000ms Memory Limit: 262144KB This problem will be judged on HDU. Original ID: 5390 ...

  9. hdu 4946 2014 Multi-University Training Contest 8

    Area of Mushroom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

随机推荐

  1. 笔记-jinja2语法

    笔记-jinja2语法 1.      基本语法 控制结构 {% %} 变量取值 {{ }} 注释 {# #} 2.      变量 最常用的是变量,由Flask渲染模板时传过来,比如上例中的”nam ...

  2. EDM站点

    设计邮件模版 http://templates.mailchimp.com/

  3. Linux下查看CPU信息[/proc/cpuinfo]

    最近在研究linux系统负载的时候,接触到一些关于CPU信息查看的知识,和大家分享一下.通过对/proc/cpuinfo文件中的参数的分析,也学到了不少东西. 在linux操作系统中,CPU的信息在启 ...

  4. MySQL日期比较

    假如有个表product有个字段add_time,它的数据类型为datetime,有人可能会这样写sql: select * from product where add_time = '2013-0 ...

  5. 怎样安装Android Studio

    在浏览器地址栏输入 http://www.android-studio.org/ 打开Android Studio中文社区, 下载安装包: 这里需要注意的是SDK的目录, 我没有选择默认的目录, 而是 ...

  6. jmeter的脚本增强之参数化

    jmeter作为一款开源的测试工具,功能广泛,深受测试同胞们的喜爱,这次来讲讲关于如何参数化及其方式.那为什么要进行一个参数化呢,如做压测时,要有大量的数据来模拟用户的真实场景,像登录页面操作,系统是 ...

  7. Python汉诺塔问题递归算法与程序

    汉诺塔问题: 问题来源:汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从上往下从小到大顺序摞着64片黄金圆盘.上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱 ...

  8. Unity编辑器 - 鼠标悬停在控件上时改变鼠标样式

    Unity编辑器 - 鼠标悬停在控件上时改变鼠标样式 摘自Unity文档 EditorGUIUtility.AddCursorRect public static void AddCursorRect ...

  9. python 终级篇 django ---ORM操作

                                       一般操作                                                          必会的 ...

  10. [Clr via C#读书笔记]Cp6类型和成员基础

    Cp6类型和成员基础 成员 常量:字段(静态字段和实例字段):实例构造器:类型构造器(用于静态字段的构造):方法(静态方法和实例方法):操作符重载(本质是一个方法):转换操作符:属性(本质还是方法): ...