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. 天津Uber优步司机奖励政策(1月11日~1月17日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  2. Netty概述

    一,介绍 Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序. 也就是说,Netty 是一 ...

  3. Unicode编码相关概念

    1.Unicode是一种字符映射方案,这种映射并不是编码(即还没有到二进制机器码层面),而是像一个电话本一样,把全世界所有语言使用的字符,都映射成一个"u+"开头的数字(在JAVA ...

  4. leetcode--笔记8 Fizz Buzz

    题目要求: Write a program that outputs the string representation of numbers from 1 to n. But for multipl ...

  5. 远离服务器宕机,腾讯WeTest正式推出服务器深度性能测试服务

    WeTest 导读 随着城市发展趋向智慧化,不仅移动互联网应用正迅速融入出行.金融.医疗.娱乐等传统行业,跟随移动互联网成长起来的,还有用户对应用使用与消费的理性意识. 而在用户不断增加的同时,如何避 ...

  6. Qt-QML-Slider-滑块-Style-后继

    首先了,先把我上篇文章的demo准备好,不过我上次写的被我删除了,这次就重新写了一个,上代码 import QtQuick 2.5 import QtQuick.Controls 1.4 import ...

  7. Micro:bit 硬件架构介绍

    Micro:bit做为当红的少儿编程工具,这两年在编程教育领域越来越火.今天就从硬件架构开始,分享Micro:bit的相关主题. Microbit 硬件设计是根据ARM mbed技术所开发的应用IC及 ...

  8. javascript常用对象方法

    concat:连接产生一个新数组 [1,2].concat([3,4])     >> [1, 2, 3, 4] filter:返回符合条件的一个新数组 [1,2,3,4,5].filte ...

  9. appium启动APP配置参数:

    一.Android启动app   python启动脚本如下:   from appium import webdriver   desired_caps = {} desired_caps['plat ...

  10. 使用深度学习来破解 captcha 验证码(转)

    使用深度学习来破解 captcha 验证码 本项目会通过 Keras 搭建一个深度卷积神经网络来识别 captcha 验证码,建议使用显卡来运行该项目. 下面的可视化代码都是在 jupyter not ...