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. Java基础——网络编程

    一.网络编程概述 概述: Java是 Internet 上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序. Java提供的网络类库,可以实现无痛的网络连接,联网 ...

  2. 20145234黄斐《信息安全系统设计基础》第七周(Linux命令复习)

    已经到了11月,学期过半,而<信息安全系统设计基础>这门课也要到了期中考试了.所以,我在这里,对前半个学期的最基础的知识,做一个复习 复习计划分为两步,本次为Linux命令,下次计划复习g ...

  3. MVC PartialView 方式实现点击加载更多

    <table id="MovieListing"> </table><div> <button id="btnShowMore& ...

  4. Caliburn.Micro 杰的入门教程3,事件和参数

    Caliburn.Micro 杰的入门教程1(翻译)Caliburn.Micro 杰的入门教程2 ,了解Data Binding 和 Events(翻译)Caliburn.Micro 杰的入门教程3, ...

  5. java 程序文本文档形式的编写,编译,及运行

    一.程序的编写 1.在指定路径下新建文本文档 如在f盘新建了一个名为demo的文件夹,在该文件夹路径下新建了一个文本文档 2.打开文本文档,进行编写,例如: 3.保存 选择文件另存为,文件名称为你创建 ...

  6. ORB-SLAM(十)LoopClosing Sim3求解

    主要参考这篇论文 Horn B K P. Closed-form solution of absolute orientation using unit quaternions[J]. JOSA A, ...

  7. Mysql忘记密码处理办法

    找回密码的步骤如下: 1.停止mysql服务器 sudo /opt/lampp/lampp stopmysql 2.使用`--skip-grant-tables' 参数来启动 mysqld sudo ...

  8. 【费元星原创】一键安装Hadoo2.7.6 集群完全分布式脚本-完美解决

    有Bug 欢迎反馈,我不烦:feiyuanxing@gmail.com 1 #!/bin/bash #@author:feiyuanxing [既然笨到家,就要努力到家] #@date:2017-01 ...

  9. Andorid自定义attr的各种坑

    本文来自网易云社区 作者:孙有军 在开发Andorid应用程序中,经常会自定义View来实现各种各样炫酷的效果,在实现这吊炸天效果的同时,我们往往会定义很多attr属性,这样就可以在XML中配置我们想 ...

  10. hdu1257最少拦截系统(暴力)

    最少拦截系统 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...