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. Django(投票程序)

    Django是一个web框架,python编写的. MTV模式 Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同 -M代表模型(Model ):负责 ...

  2. 【Redis3.0.x】实战案例

    Redis3.0.x 实战案例 简介 <Redis实战>的学习笔记和总结. 书籍链接 初识 Redis Redis 简介 Redis 是一个速度非常快的键值对存储数据库,它可以存储键和五种 ...

  3. 详细的String源码解析

    我们常常把String类型的字符串作为HashMap的key,为什么要这样做呢? 因为String是不可变的,一旦初始化就不再改变了,如果被修改将会是一个新对象. @Test public void ...

  4. Soat控制HAProxy 动态增减服务器

    Soat控制HaProxy 动态增减服务器 安装HaProxy-1.5.18: yum install haproxy -y yum install socat -y HaProxy-1.5.18 配 ...

  5. python模块详解 | filecmp

    简介: filecmp是python内置的一个模块,用于比较文件及文件夹的内容,它是一个轻量级的工具,使用非常简单 两个主要的方法: filecmp.cmp(f1, f2[, shallow]) 比较 ...

  6. 【RAC】安装rac的时候。报错checking for oracle home incompatibilities failed

    背景:由于oracle安装的时候中途出现了问题,解决过后,发现报错了 图形化安装的时候,有这个问题出现 解决办法: 删除安装过的所有缓存,和文件即可 1.删除ORACLE_BASE下的所有文件 2.删 ...

  7. 1V升压5V和1.5V升压5V的集成电路芯片

    1.5V和1V输入,要升压输出5V的集成电路芯片合适? 干电池标准电压是1.5V,放电电压后面在0.9V-1V左右,如果要选用干电池1.5V升压到5V的合适的芯片,需要满足低压1V或者0.9V更好的低 ...

  8. uni-app开发经验分享十: 封装request请求

    http.js //封装requset,uploadFile和downloadFile请求,新增get和post请求方法 let http = { 'setBaseUrl': (url) => ...

  9. 【Android初级】如何动态添加菜单项(附源码+避坑)

    我们平时在开发过程中,为了灵活多变,除了使用静态的菜单,还有动态添加菜单的需求.今天要分享的功能如下: 在界面的右上角有个更多选项,点开后,有两个子菜单:关于和退出 点击"关于", ...

  10. Linux 三剑客之 grep 使用详解

    Linux 最重要的三个命令在业界被称为三剑客,它们是:awk.sed.grep.sed 已经在上篇中讲过,本文要讲的是 grep 命令. 我们在使用 Linux 系统中,grep 命令的使用尤为频繁 ...