2017 Multi-University Training Contest - Team 1

01     签到的

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 200005;int main()
{int n, cas=0;while(~scanf("%d", &n)){printf("Case #%d: %d\n", ++cas, (int)(log10(2)*n));}return 0;
}

View Code

02     模拟

记:sort 比较函数cmp,如果最后相等,应该返回 false,否则会错。。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 100000+200, mod = 1e9+7;string s[N];
bool is[27];
int n, mx[27];
ll  num[27][N];
struct Str { string si; int len, id; } str[27];
void Init()
{mes(num,0);  mes(is, 0);
}
bool cmp(Str a, Str b)
{if(a.len!=b.len) return a.len < b.len;for(int j=a.len-1; j>=0; j--) if(a.si[j]!=b.si[j]) {if(a.si[j] < b.si[j]) return true;if(a.si[j] > b.si[j]) return false;}return false;   ////string s1=a.si, s2=b.si;//reverse(s1.begin(),s1.end()), reverse(s2.begin(),s2.end());//return s1<s2;
}
ll  fpow(ll a, int b) {ll ans=1; for(;b;a=a*a%mod, b>>=1)if(b&1)ans=ans*a%mod; return ans; }
int main()
{int cas=0;while(~scanf("%d", &n)){Init();rep(i,1,n) {cin>>s[i];if(s[i].length()!=1) is[s[i][0]-'a']=1;}mes(mx, 0);rep(i,1,n) {int len=s[i].length();for(int j=len-1; j>=0; --j){int ch = s[i][j]-'a';++num[ch][len-j-1];mx[ch] = max(mx[ch], len-j);}}rep(i,0,25) {int len=0;str[i].si="";for(int j=0; j<mx[i]; ++j){num[i][j+1] += num[i][j]/26;num[i][j] %= 26;if(num[i][j+1]) mx[i] = max(mx[i], j+2);str[i].si += ('a'+num[i][j]);}str[i].len=mx[i], str[i].id=i;}sort(str, str+26, cmp);int flag=0;rep(i,0,25) {int ch = str[i].id;if(is[ch]==0) { flag=i; break; }}ll  ans=0;rep(i,0,25) {ll val = flag==i ? 0 : (flag>i ? i+1 : i);for(int j=0; j<str[i].len; ++j) {( ans += val*(str[i].si[j]-'a')*(fpow(26,j)%mod) ) %= mod;}}printf("Case #%d: %lld\n", ++cas, ans);}return 0;
}

View Code

03     树形dp,好题

题意: 求一棵树上所有路径不同权值个数的和。

tags: 看了题解才做出来。。

官方题解:单独考虑每一种颜色,答案就是对于每种颜色至少经过一次这种的路径条数之和。反过来思考只需要求有多少条路径没有经过这种颜色即可。直接做可以采用虚树的思想(不用真正建出来),对每种颜色的点按照 dfs 序列排个序,就能求出这些点把原来的树划分成的块的大小。这个过程实际上可以直接一次 dfs 求出。

直观地说,对于每种颜色,假设它在所有路径中都出现,即 n*(n-1)/2次,再减去它没有出现过的路径数量就是答案。 然后它没有出现过的路径数量怎么算呢?  对于每种颜色,把它出现的地方在树上标出,发现它会把树划分成多个块,而在每个块中它是没有出现的,所以就转化成了求每种颜色划分出来的各个块的大小。 各个块的大小该怎么求呢? 这里就是树dp 来实现了。

设sum[i]为已经dfs遍历过的点中,以颜色i 的点为根的子树的节点个数之和。当dfs遍历到节点 u 时,对于它的一个儿子节点 to,先进入 to 进行dfs。如果子树 to 中有颜色col[u]的点,sum[col[u]] 就会跟着变化。假设 sum[col[u]] 增加了num, 那么节点 to 下面就应该有 size[to]-num个颜色不为 col[u]的点还没有计算过,即 to 连着的块大小为 tmp=size[to]-num,把 tmp*(tmp-1)/2 加入到答案。 然后 sum[col[u]] += tmp 进行维护即可。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 200005;int n, col[N], head[N<<1], tot, Size[N], cnt;
bool vis[N];
ll  sum[N], ans;
struct Edge{int to,next; } e[N<<1];
void Addedge(int u,int v) {e[tot]={v,head[u] }; head[u]=tot++; }
void dfs(int u, int fa)
{Size[u]=1;for(int i=head[u]; i!=-1; i=e[i].next) if(e[i].to!=fa){ll  s=sum[col[u]];dfs(e[i].to, u);Size[u] += Size[e[i].to];ll  num=sum[col[u]]-s, tmp=Size[e[i].to]-num;ans += tmp*(tmp-1)/2, sum[col[u]] += tmp;}++sum[col[u]];
}
void Init()
{mes(head, -1);  mes(sum, 0);  mes(Size, 0);ans = 0, tot = 0;mes(vis, 0);  cnt=0;
}
int main()
{int cas=0;while(~scanf("%d", &n)){Init();rep(i,1,n) {scanf("%d", &col[i]);if(vis[col[i]]==0) vis[col[i]]=1, ++cnt;}int a, b;rep(i,1,n-1) {scanf("%d %d", &a, &b);Addedge(a, b);  Addedge(b, a);}dfs(1, 0);rep(i,1,n) if(vis[i] && i!=col[1]) {ans += 1LL*(n-sum[i])*(n-sum[i]-1)/2;}ans = 1LL*cnt*n*(n-1)/2-ans;printf("Case #%d: %lld\n", ++cas, ans);}return 0;
}

View Code

06     置换群

题意:给出两个数组,求满足 f(i)=b[f(a[i])] 关系的f()有多少个。

tags:把b[] 里面的环放入 a[] 里面,然后a[] 的环应该是 b[] 的环的倍数,且一个 a[i]不能对应多个 b[] 。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 100005, mod = 1e9+7;bool vis[N];
int mx;
int cal(ll *a, int len, ll *num)
{mes(vis, 0);int sum=0;for(int i=0; i<len; ++i) if(vis[i]==0){++sum;int cnt=0, t=i;while(vis[t]==0){vis[t]=1, ++cnt, t=a[t];}++num[cnt];mx=max(mx, cnt);}return sum;
}
ll  a[N], b[N], num1[N], num2[N];
bool flag1[N];
void Init()
{mes(num1, 0);  mes(num2, 0);  mes(flag1, 0);mx=0;
}
ll fpow(ll a,ll b) {ll ans=1; for(;b;a=a*a%mod, b>>=1)if(b&1)ans=ans*a%mod; return ans; }
int main()
{int cas=0, n, m;while(~scanf("%d %d", &n, &m)){Init();for(int i=0; i<n; ++i) scanf("%lld", &a[i]);for(int i=0; i<m; ++i) scanf("%lld", &b[i]);int cnt1=cal(a, n, num1), cnt2=cal(b, m, num2);ll  ans=1;for(int i=1; i<=mx; ++i) if(num1[i]){ll  res=0;for(int j=i; j>0; --j) if(num2[j] && i%j==0){( res += num2[j]*j%mod ) %= mod;}( ans *= (fpow(res,num1[i]) )) %= mod;}printf("Case #%d: ", ++cas);printf("%lld\n", (ans+mod)%mod);}return 0;
}

View Code

08     快排思想,线性复杂度求第 k小

题意:给出 n,m,A,B,C,其中 ABC为3个参数,用这三个参数可以生成n个数a[i] 。有 m个数b[i],对于每一个b[i],我们要找出在 a[] 数组中第 b[i]+1 小的数。

tags: T 到死的节奏。。

官方题解:

快速排序思想 : 设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。

也就是利用快排思想,我们可以快速地把第 k 小的数找出来,而比它小的数都会换到它的左边,比它大的数都会换到它右边。这样就可以依次减少枚举的数量,达到O(n)复杂度。

类似快排思想:

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef  long long  ll;
const int N = 10000005;unsigned  a[N], A, B, C, ans[110];
int n, m;
bool vis[N];
void Qsort(int ki, int l, int r)
{int i=l, j=r, k=l;while(i<j){for(; i<j; --j) if(a[j]<a[k]){swap(a[j], a[k]);   k=j;break;}for(; i<j; ++i) if(a[i]>a[k]){swap(a[i], a[k]);   k=i;break;}}vis[k] = 1;if(l<k && ki<k) Qsort(ki, l, k-1);if(k<r && k<ki) Qsort(ki, k+1, r);
}
int main()
{int cas=0;while(~scanf("%d %d %lu %lu %lu", &n, &m, &A, &B, &C)){mes(vis, false);unsigned  x = A, y = B, z = C, t;rep(i,1,n){x ^= (x<<16); x ^= (x>>5); x ^= (x<<1);t=x, x=y, y=z, z=t^x^y;a[i] = z;}int bi;rep(i,1,m){scanf("%d", &bi);    ++bi;int l=bi, r=bi;for(; l>0 && vis[l]==0; --l) ;   ++l;for(; r<=n && vis[r]==0; ++r) ;  --r;Qsort(bi, l, r);ans[i] = a[bi];}printf("Case #%d:", ++cas);rep(i,1,m) printf(" %lu", ans[i]);puts("");}return 0;
}

View Code

STL中的 nth_element(arr, arr+x, arr+n) 直接排:

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef  long long  ll;
const int N = 10000005;unsigned  a[N], A, B, C, ans[110];
int n, m;
pair<int , int > b[110];
int main()
{int cas=0;while(~scanf("%d %d %lu %lu %lu", &n, &m, &A, &B, &C)){unsigned  x = A, y = B, z = C, t;for(int i=1; i<=n; ++i){x ^= (x<<16); x ^= (x>>5); x ^= (x<<1);t=x, x=y, y=z, z=t^x^y;a[i] = z;}for(int i=1; i<=m; ++i){scanf("%d", &b[i].fi);++b[i].fi,  b[i].se=i;}sort(b+1, b+1+m);b[m+1].fi=n;for(int i=m; i>0; --i){if(i!=m && b[i].fi==b[i+1].fi) {   // 没加这个优化就超时了。。ans[b[i].se] = ans[b[i+1].se];continue;}nth_element(a+1, a+b[i].fi, a+1+b[i+1].fi);ans[b[i].se] = a[b[i].fi];}printf("Case #%d:", ++cas);for(int i=1; i<=m; ++i) printf(" %lu", ans[i]);puts("");}return 0;
}

View Code

11     水

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 200005;int main()
{int cas=0;ll  n, k;while(~scanf("%lld %lld", &n, &k)){ll  pos;if(k<=n) pos=k;else{k -= n;ll  cnt1=k/(n-1), cnt2=k%(n-1);if(cnt2==0) pos = cnt1&1 ? n-1 : n;else pos=cnt2;}printf("Case #%d: %lld\n", ++cas, pos);}return 0;
}

View Code

转载于:https://www.cnblogs.com/sbfhy/p/7240408.html

2017 Multi-University Training Contest - Team 1相关推荐

  1. 2017 Multi-University Training Contest - Team 3 Kanade's sum hd6058

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6058 题目: Kanade's sum Time Limit: 4000/2000 MS (J ...

  2. 2017 Multi-University Training Contest - Team 7:1003. Color the chessboard(...)

    其他题目题解: 2017 Multi-University Training Contest - Team 7:1005. Euler theorem 2017 Multi-University Tr ...

  3. 2017 Multi-University Training Contest - Team 7:1002. Build a tree(递归)

    其他题目题解: 2017 Multi-University Training Contest - Team 7:1005. Euler theorem 2017 Multi-University Tr ...

  4. 2017 Multi-University Training Contest - Team 7:1010. Just do it(组合数?)

    其他题目题解: 2017 Multi-University Training Contest - Team 7:1005. Euler theorem 2017 Multi-University Tr ...

  5. 2017 Multi-University Training Contest - Team 7:1008. Hard challenge(模拟)

    其他题目题解: 2017 Multi-University Training Contest - Team 7:1005. Euler theorem 2017 Multi-University Tr ...

  6. 2017 Multi-University Training Contest - Team 7:1011. Kolakoski(模拟)

    其他题目题解: 2017 Multi-University Training Contest - Team 7:1005. Euler theorem 2017 Multi-University Tr ...

  7. 2017 Multi-University Training Contest - Team 7:1005. Euler theorem(答案是(n+3)/2)

    其他题目题解: 2017 Multi-University Training Contest - Team 7:1003. Color the chessboard 2017 Multi-Univer ...

  8. 2017 Multi-University Training Contest - Team 2 Puzzle

    题目大意: 给定n, m, p.然后按照一个规则往n*m的方格里填数,最后一个方格是空格,然后玩拼图游戏,问能否复原 规则是:把1~n*m-1的排列中的第1,p+1,2*p+1.....个数依次取出来 ...

  9. 2017 Multi-University Training Contest - Team 1—HDU6040

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6040 题意:不知道北航的同学为何解释题意之前都要想一段故事,导致刚开始题意不是很懂,题意就是给你n,m ...

最新文章

  1. css层叠样式表(一)
  2. python汉字转到ascii码_python中字母与ascii码的相互转换
  3. raid5通常需要几块盘_raid5需要几块硬盘
  4. Python执行 SQL 命令并实时打印输出
  5. Office2016打开doc字符间距过小
  6. Python中import和from......import的区别
  7. (JAVA)StringBuffer类(练习)
  8. vps搭建网站服务器,vps如何架设网站服务器
  9. css3 2D动画效果 200303
  10. 引用和指针自增的不同
  11. 奥运五环(一键复制)
  12. FATAL:gpu_data_manager_impl_private.cc The display compositor is frequently crashing. Goodbye.
  13. iOS13的暗黑模式
  14. 计算机无法快速预览pdf,电脑中无法使用火狐浏览器预览PDF文档怎么解决
  15. xposed 框架学习
  16. python 打印一定范围的素数(质数)
  17. 数据分析案例-往届世界杯数据可视化
  18. 云虚拟主机、云服务器、VPS三者有什么区别?
  19. 测试管理之--测试培训
  20. 中文医疗NLP榜单-CBLUE介绍

热门文章

  1. 使用minidom来处理XML的示例(Python 学习)(转载)
  2. 信息系统项目管理02——信息系统项目管理基础
  3. Oracle使用sys用户exp备份数据
  4. [转]ubuntu使用meld/beyond compare 做git的diff工具
  5. 计算机三维技术在影视广告设计中应用的研究 罗晋,计算机三维技术在影视广告设计中应用的研究...
  6. 数据分析常用的7大思维方法详解
  7. 现代人必须掌握的成功学方法
  8. html绘制城堡,HTML5动画 - 山谷城堡
  9. mysql删除表外键_MySQL删除所有表的外键约束、禁用外键约束
  10. php 使用json 教程,PHP使用JSON 教程