Educational Codeforces Round 17

A. k-th divisor

水题,把所有因子找出来排序然后找第\(k\)大

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
typedef long long int LL; void solve(){
LL n, k;
cin >> n >> k;
vector<LL> fac1;
vector<LL> fac2;
for(int i = 1; 1ll * i * i <= n; i++){
if(n%i) continue;
fac1.push_back(i);
if(i!=n/i) fac2.push_back(n/i);
}
reverse(fac2.begin(),fac2.end());
for(LL x : fac2) fac1.push_back(x);
if(k>fac1.size()) cout << -1 << endl;
else cout << fac1[k-1] << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
// int tt; for(scanf("%d",&tt); tt--; solve());
solve();
return 0;
}

B. USB vs. PS/2

显然先把两种独立的能配的尽量给配了,最后再去配都适配的

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
typedef long long int LL;
void solve(){
static int a, b, c;
vector<int> v1, v2;
____();
cin >> a >> b >> c;
int n; cin >> n;
for(int i = 1; i <= n; i++){
int x; string s;
cin >> x >> s;
if(s[0]=='U') v1.push_back(x);
else v2.push_back(x);
}
sort(v1.begin(),v1.end());
sort(v2.begin(),v2.end());
int ptr1 = 0, ptr2 = 0;
int cnt = 0;
LL ret = 0;
while(ptr1<v1.size() and a){
ret += v1[ptr1++];
a--;
cnt++;
}
while(ptr2<v2.size() and b){
ret += v2[ptr2++];
b--;
cnt++;
}
while(c){
if(ptr1==v1.size() and ptr2==v2.size()) break;
c--; cnt++;
if(ptr1==v1.size()) ret += v2[ptr2++];
else if(ptr2==v2.size()) ret += v1[ptr1++];
else if(v1[ptr1]<v2[ptr2]) ret += v1[ptr1++];
else ret += v2[ptr2++];
}
cout << cnt << ' ' << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}

C. Two strings

显然\(b\)串需要删掉中间的部分,也就是保留前缀和后缀

记一下\(b\)串前面能保留\(x\)个的情况下在\(a\)串中的最后匹配位置和\(a\)串后面还有\(x\)个位置的情况下最多能匹配\(b\)串的后缀长度

注意合并了之后串长不能超过\(a\)串或者\(b\)串的长度

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+8; char s1[MAXN], s2[MAXN];
int nxt[MAXN][26], n, m, pos[MAXN], rpos[MAXN];
void solve(){
cin >> s1+1 >> s2+1;
n = strlen(s1 + 1);
m = strlen(s2 + 1);
for(int i = 0; i < 26; i++) nxt[n][i] = MAXN;
for(int i = n - 1; i >= 0; i--){
for(int j = 0; j < 26; j++) nxt[i][j] = nxt[i+1][j];
nxt[i][s1[i+1]-'a'] = i + 1;
}
for(int i = 1; i <= n; i++) pos[i] = MAXN;
int ptr = 0, now = 1;
while(now <= m and nxt[ptr][s2[now]-'a']!=MAXN){
ptr = nxt[ptr][s2[now]-'a'];
pos[now] = ptr;
now++;
}
reverse(s1+1,s1+1+n);
reverse(s2+1,s2+1+m);
for(int i = 0; i < 26; i++) nxt[n][i] = MAXN;
for(int i = n - 1; i >= 0; i--){
for(int j = 0; j < 26; j++) nxt[i][j] = nxt[i+1][j];
nxt[i][s1[i+1]-'a'] = i + 1;
}
ptr = 0, now = 1;
while(now <= m and nxt[ptr][s2[now]-'a']!=MAXN){
ptr = nxt[ptr][s2[now]-'a'];
rpos[n-ptr+1] = now;
now++;
}
for(int i = n; i >= 0; i--) rpos[i] = max(rpos[i],rpos[i+1]);
int maxx = 0, ps = -1;
for(int i = 0; i <= m; i++){
if(pos[i]==MAXN) break;
if(i+rpos[pos[i]+1]>=maxx){
maxx = i + rpos[pos[i]+1];
ps = i;
}
}
if(maxx==0) cout << "-" << endl;
else{
string a, b;
int rmatch = rpos[pos[ps]+1];
b = string(s2+1,s2+1+rmatch);
reverse(s2+1,s2+1+m);
a = string(s2+1,s2+1+ps);
reverse(b.begin(),b.end());
if(maxx>=m){
if(maxx<=n) cout << s2 + 1 << endl;
else cout << string(s2+1,s2+1+n) << endl;
}
else{
if(maxx<=n) cout << a + b << endl;
else cout << a + string(b.begin()+b.size()+a.size()-maxx,b.end()) << endl;
}
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
// int tt; for(scanf("%d",&tt); tt--; solve());
solve();
return 0;
}

D. Maximum path

如果又往右走又往左走很麻烦,其实可以发现,连续往右走大于两步的情况都可以被分解成小于等于两步的走法,转移即可

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
typedef long long int LL;
int n, A[4][MAXN];
LL f[4][MAXN];
inline void cmax(LL &x, LL y){ x = x > y ? x : y; }
void solve(){
scanf("%d",&n);
memset(f,-0x3f,sizeof(f));
for(int i = 1; i <= 3; i++) for(int j = 1; j <= n; j++) scanf("%d",&A[i][j]);
f[1][1] = A[1][1]; f[2][1] = f[1][1] + A[2][1]; f[3][1] = f[2][1] + A[3][1];
f[3][2] = 0ll + A[1][1] + A[1][2] + A[2][2] + A[2][1] + A[3][1] + A[3][2];
for(int i = 1; i < n; i++){
cmax(f[2][i+1],f[2][i] + A[2][i+1]);
cmax(f[1][i+1],f[1][i] + A[1][i+1]);
cmax(f[3][i+1],f[3][i] + A[3][i+1]);
cmax(f[2][i+1],f[1][i] + A[1][i+1] + A[2][i+1]);
cmax(f[2][i+1],f[3][i] + A[3][i+1] + A[2][i+1]);
cmax(f[1][i+1],f[2][i] + A[2][i+1] + A[1][i+1]);
cmax(f[3][i+1],f[2][i] + A[2][i+1] + A[3][i+1]);
cmax(f[1][i+1],f[3][i] + A[3][i+1] + A[2][i+1] + A[1][i+1]);
cmax(f[3][i+1],f[1][i] + A[1][i+1] + A[2][i+1] + A[3][i+1]);
if(i + 2 > n) continue;
cmax(f[1][i+2],f[3][i] + A[3][i+1] + A[3][i+2] + A[2][i+2] + A[2][i+1] + A[1][i+1] + A[1][i+2]);
cmax(f[3][i+2],f[1][i] + A[1][i+1] + A[1][i+2] + A[2][i+2] + A[2][i+1] + A[3][i+1] + A[3][i+2]);
}
cout << f[3][n] << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}

E. Radio stations

因为两个接触的距离限制中半径要取\(\min\),所以考虑按半径大到小排序,把所有位置离散化一下,由于\(k\le 10\)然后每次只需要找对应的频率区间在可影响范围内有多少点即可,然后每次再把枚举的点放到对应的线段树里去

这里考虑动态开点权值线段树来做

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 5e5+7; vector<int> vec;
int n, k;
pair<pair<int,int>,int> sta[MAXN];
struct segtree{
int root[MAXN], sum[MAXN<<5], ls[MAXN<<5], rs[MAXN<<5], tot;
#define pushup(rt) sum[rt] = sum[ls[rt]] + sum[rs[rt]]
void modify(int l, int r, int pos, int &rt){
if(!rt) rt = ++tot;
sum[rt] += 1;
if(l+1==r) return;
int mid = (l + r) >> 1;
if(pos<mid) modify(l,mid,pos,ls[rt]);
else modify(mid,r,pos,rs[rt]);
}
int Q(int L, int R, int l, int r, int rt){
if(L>=r or l>=R) return 0;
if(L<=l and r<=R) return sum[rt];
int mid = (l + r) >> 1;
return Q(L,R,l,mid,ls[rt]) + Q(L,R,mid,r,rs[rt]);
}
}ST;
int exc(int x){ return lower_bound(vec.begin(),vec.end(),x) - vec.begin() + 1; }
void solve(){
scanf("%d %d",&n,&k);
for(int i = 1; i <= n; i++){
scanf("%d %d %d",&sta[i].first.first,&sta[i].second,&sta[i].first.second);
vec.push_back(sta[i].first.first-sta[i].second);
vec.push_back(sta[i].first.first+sta[i].second);
vec.push_back(sta[i].first.first);
}
sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(),vec.end()),vec.end());
sort(sta+1,sta+1+n,[](const pair<pair<int,int>,int> &A, const pair<pair<int,int>,int> &B){
return A.second > B.second;
});
long long int ret = 0;
for(int i = 1; i <= n; i++){
int p = exc(sta[i].first.first);
int l = exc(sta[i].first.first-sta[i].second);
int r = exc(sta[i].first.first+sta[i].second);
for(int f = max(1,sta[i].first.second-k); f <= sta[i].first.second+k; f++) ret += ST.Q(l,r+1,1,MAXN,ST.root[f]);
ST.modify(1,MAXN,p,ST.root[sta[i].first.second]);
}
cout << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}

F. Tree nesting

在大树里面找小树,大树随意定根,接下来我们枚举小树的根,如果某个小树和之前枚举的同构了就直接跳过同构当然用树哈希来判断,,然后用小树和大树匹配,令\(f[i][j]\)表示大树的节点\(i\)和小树的节点\(v\)匹配的方案数,接下来我们对小树\(dfs\)一遍,每次枚举和当且节点匹配的大树节点

当当前点是小树的叶子节点石,方案数显然是\(1\)

否则考虑状压\(DP\)转移,假设当前石小树的\(u\)节点和大树的\(x\)节点匹配,那么找出两者所有的儿子,然后\(dp[i][msk]\)表示当前枚举到\(x\)的第\(i\)个儿子,当前已经匹配的\(u\)的子节点集合为\(msk\)的方案数,转移很好转,如果\(u\)的子节点有同构又要除掉阶乘,否则会有重复计算

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1111;
const int MOD = 1e9+7;
vector<int> GS[MAXN], GT[MAXN];
int n, m, fac[20], inv[20], rfac[20], prime[] = {0,2,3,5,7,11,13,17,19,23,29,31,37,41};
int ret, sz[20], hax[20], fas[MAXN], fat[20];
set<int> vishash;
void dfss(int u, int par){
fas[u] = par;
for(int v : GS[u]) if(v!=par) dfss(v,u);
}
void dfs(int u, int par){
sz[u] = hax[u] = 1;
fat[u] = par;
for(int v : GT[u]){
if(v==par) continue;
dfs(v,u);
sz[u] += sz[v];
hax[u] = (hax[u] + hax[v] * prime[sz[v]]) % MOD;
}
}
int f[20][MAXN];
void match(int u){
for(int v : GT[u]) if(v!=fat[u]) match(v);
if((GT[u].size()==1 and fat[u]) or GT[u].empty()){
for(int i = 1; i <= n; i++) f[u][i] = 1;
return;
}
vector<int> sont;
map<int,int> cnt;
for(int v : GT[u]) if(v!=fat[u]){
sont.push_back(v);
cnt[hax[v]]++;
}
int ff = 1;
for(auto p : cnt) ff = (1ll * ff * rfac[p.second]) % MOD;
for(int x = 1; x <= n; x++){
// try match u and x
vector<int> sons;
for(int v : GS[x]) if(v!=fas[x]) sons.push_back(v);
vector<vector<int> > dp(2,vector<int>(1<<sont.size()));
dp[0][0] = 1; int tag = 1;
for(int i = 0; i < (int)sons.size(); i++, tag ^= 1){
dp[tag] = dp[tag^1];
for(int msk = 0; msk < (1<<sont.size()); msk++){
for(int bit = 0; bit < (int)sont.size(); bit++){
if(msk>>bit&1) continue;
dp[tag][msk|(1<<bit)] = (dp[tag][msk|(1<<bit)] + 1ll * dp[tag^1][msk] * f[sont[bit]][sons[i]]) % MOD;
}
}
}
f[u][x] = 1ll * dp[tag^1][(1<<sont.size())-1] * ff % MOD;
}
}
void test(int id){
dfs(id,0);
if(vishash.count(hax[id])) return;
vishash.insert(hax[id]);
memset(f,0,sizeof(f));
match(id);
for(int i = 1; i <= n; i++) ret = (ret + f[id][i]) % MOD;
}
void solve(){
scanf("%d",&n);
for(int i = 1; i < n; i++){
int u, v; scanf("%d %d",&u,&v);
GS[u].push_back(v);
GS[v].push_back(u);
}
scanf("%d",&m);
for(int i = 1; i < m; i++){
int u, v; scanf("%d %d",&u,&v);
GT[u].push_back(v);
GT[v].push_back(u);
}
dfss(1,0);
for(int i = 1; i <= m; i++) test(i);
cout << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
fac[0] = rfac[0] = inv[1] = 1;
for(int i = 1; i < 20; i++) fac[i] = 1ll * i * fac[i-1] % MOD;
for(int i = 2; i < 20; i++) inv[i] = 1ll * (MOD - MOD / i) * inv[MOD%i] % MOD;
for(int i = 1; i < 20; i++) rfac[i] = 1ll * inv[i] * rfac[i-1] % MOD;
solve();
return 0;
}

Educational Codeforces Round 17的更多相关文章

  1. Educational Codeforces Round 17 颓废记

    又被虐了... (记一次惨痛的Codeforces) 好不容易登上去了Codeforces,22:35准时开打 第一题,一看:这不SB题嘛?直接枚举因数上啊.9min才过掉了pretest 第二题.. ...

  2. Educational Codeforces Round 17 D. Maximum path DP

    题目链接:http://codeforces.com/contest/762/problem/D 多多分析状态:这个很明了 #include<bits/stdc++.h> using na ...

  3. Educational Codeforces Round 17 C. Two strings 打表二分

    C. Two strings time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  4. Codeforces Educational Codeforces Round 17 Problem.A kth-divisor (暴力+stl)

    You are given two integers n and k. Find k-th smallest divisor of n, or report that it doesn't exist ...

  5. Educational Codeforces Round 71 (Rated for Div. 2)-E. XOR Guessing-交互题

    Educational Codeforces Round 71 (Rated for Div. 2)-E. XOR Guessing-交互题 [Problem Description] ​ 总共两次询 ...

  6. [Educational Codeforces Round 16]E. Generate a String

    [Educational Codeforces Round 16]E. Generate a String 试题描述 zscoder wants to generate an input file f ...

  7. [Educational Codeforces Round 16]D. Two Arithmetic Progressions

    [Educational Codeforces Round 16]D. Two Arithmetic Progressions 试题描述 You are given two arithmetic pr ...

  8. [Educational Codeforces Round 16]C. Magic Odd Square

    [Educational Codeforces Round 16]C. Magic Odd Square 试题描述 Find an n × n matrix with different number ...

  9. [Educational Codeforces Round 16]B. Optimal Point on a Line

    [Educational Codeforces Round 16]B. Optimal Point on a Line 试题描述 You are given n points on a line wi ...

随机推荐

  1. Dota游戏匹配的所有组合

    在Dota游戏中有一种匹配玩法,任意5人以下玩家组队,加入匹配系统,由系统组合出5人 vs 5人的组合进行游戏,比如2人+3人  vs 1人+4人.抽象出这个问题,就变成两边各有m个玩家,最多允许n个 ...

  2. Docker-Docker部署SpringBoot项目

    1.手工方式 1.1.准备Springboot jar项目 将项目打包成jar 1.2.编写Dockerfile FROM java:8 VOLUME /tmp ADD elk-web-1.0-SNA ...

  3. 一文读懂 SuperEdge 边缘容器架构与原理

    前言 superedge是腾讯推出的Kubernetes-native边缘计算管理框架.相比openyurt以及kubeedge,superedge除了具备Kubernetes零侵入以及边缘自治特性, ...

  4. Java内存模型与线程(一)

    Java内存模型与线程 TPS:衡量一个服务性能的标准,每秒事务处理的总数,表示一秒内服务端平均能够响应的总数,TPS又和并发能力密切相关. 在聊JMM(Java内存模型)之前,先说一下Java为什么 ...

  5. iTerm2 实现 ssh 自动登录,并使用 Zmodem 实现快速传输文件

    原文链接:https://fuckcloudnative.io/posts/iterm2-auto-login/ 对于 YAML 工程师来说,我们经常需要 ssh 登录不同的服务器,每次登录时都要经历 ...

  6. LeetCode530. 二叉搜索树的最小绝对差

    题目 又是常见的BST,要利用BST的性质,即中序遍历是有序递增序列. 法一.中序遍历 1 class Solution { 2 public: 3 vector<int>res; 4 v ...

  7. CSRF - Pikachu

    概述: Cross-site request forgery 简称为"CSRF"(跨站请求伪造),在CSRF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接),然后欺骗目标 ...

  8. disfunc绕过

    绕过DisFunc的常见小技巧 解析webshell命令不能执行时的三大情况 一是 php.ini 中用 disable_functions 指示器禁用了 system().exec() 等等这类命令 ...

  9. 数据分析 Pandas 简介和它的的数据结构

    本文主要讲Pandas 的Series和DataFrame 的相关属性和操作 1.Series的相关属性和操作# --Series是一种类似于一维数组的对象,只能存放一维数组!由以下两部分组成:# v ...

  10. ALV中layout布局控制详解

    参数的结构为SLIS_LAYOUT_ALV.结构中比较常用的字段如下: no_colhead      隐藏列标题          值为X或空 no_hotspot     headings不作为热 ...