A. Arithmetic Derivative

形如$p^p(p是质数)$的数的比值为$1$,用$k$个这种数相乘得到的数的比值为$k$,爆搜即可。

#include<cstdio>
#include<algorithm>
typedef unsigned long long ll;
int K,cnt,all;ll n,i,q[100000],ans[1000000];
ll po(ll a,ll b){ll t=1;while(b--){if(t>n/a)return n+1;t*=a;}return t;
}
bool isprime(ll n){for(ll i=2;i<n;i++)if(n%i==0)return 0;return 1;
}
void dfs(int x,ll y,int k){if(y>n)return;//printf("%d %llu %d\n",x,y,k);if(k==K){ans[++all]=y;return;}if(x>cnt)return;dfs(x+1,y,k);if(y<=n/q[x])dfs(x,y*q[x],k+1);
}
int main(){scanf("%d%llu",&K,&n);for(i=2;;i++){if(po(i,i)>n)break;if(isprime(i))q[++cnt]=po(i,i);}dfs(1,1,0);printf("%d\n",all);std::sort(ans+1,ans+all+1);for(i=1;i<=all;i++)printf("%llu ",ans[i]);
}

  

B. White Triangle

留坑。

C. New Street

用set维护相同连续段,每次新增贡献时利用多项式求幂,删除贡献则采用多项式求逆。

D. Clones and Treasures

贪心,每次不满足条件了就把前面全部舍弃。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 1e6 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
char s[N];
int n;
int main()
{while(~scanf("%s", s + 1)){n = strlen(s + 1);int sum = 0, num = 0;int ans = 0;for(int i = 1; i <= n; ++i){int val;if(s[i] == 'H')val = 1;else val = (s[i] == 'M' ? 0 : -1);sum += val;num += (val == 0);if(sum < 0){sum = num = 0;}else{gmax(ans, num);}}printf("%d\n", ans);}return 0;
}
/*
【trick&&吐槽】【题意】【分析】【时间复杂度&&优化】*/

  

E. Space Tourists

当$n>k$时答案为$k$。

否则最优策略是将$k$个数平均分成$n-1$组,每组$size(size-1)$个字符串,外加$k$个两个字符相等的字符串。

F. Matrix Game

最小表示法。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 105, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int n, m;
char s[N][N];
struct A
{string s;bool operator < (const A & b)const{return s < b.s;}
}line[N], list[N];
int main()
{while(~scanf("%d%d", &n, &m)){for(int i = 1; i <= n; ++i){scanf("%s", s[i] + 1);line[i].s = s[i] + 1;}for(int i = 1; i <= m; ++i){string now = "";for(int j = 1; j <= n; ++j){now = now + s[j][i];}list[i].s = now;}sort(line + 1, line + n + 1);sort(list + 1, list + m + 1);string ans = "";for(int i = 1; i <= n; ++i){string body = "";for(int j = n; j >= 1; --j)if(j != i){body = body + line[j].s;}for(int j = 0; j < m; ++j){string tmp = line[i].s.substr(j)+body+line[i].s.substr(0, j);gmax(ans, tmp);}}for(int i = 1; i <= m; ++i){string body = "";for(int j = m; j >= 1; --j)if(j != i){body = body + list[j].s;}for(int j = 0; j < n; ++j){string tmp = list[i].s.substr(j) + body + list[i].s.substr(0, j);gmax(ans, tmp);}}int g = ans.size();int st = g - 1;for(int i = 0; i < g; ++i)if(ans[i] != '0'){st = i;break;}cout << ans.substr(st) << endl;}return 0;
}
/*
【trick&&吐槽】【题意】【分析】【时间复杂度&&优化】
2 3
000
001*/

  

G. Milkland

留坑。

H. Parallel Relay

假如知道了所有数,那么可以等效成只有最小值和最大值的情况。

对于每一段,将所有数翻折到左边后排序,那么最小值和最大值分别是从左往右的第一个未翻折到右侧和翻折到右侧的,共$O(n)$种情况,枚举即可。

时间复杂度$O(n\log n)$。

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100010;
int n,m,i,j,a[N],b[N],c[N],ans;
inline int cal(int a,int b,int c,int d){int ret=~0U>>1;for(int i=0;i<2;i++){swap(c,d);ret=min(ret,abs(a-c)+abs(c-d)+abs(d-b));}return ret;
}
int solve(int L,int R){int i,j;int cnt=0;for(i=L;i<=R;i++){c[++cnt]=b[i];}for(i=2;i<cnt;i++)c[i]=min(c[i],m-c[i]+1);sort(c+2,c+cnt);if(cnt==2)return abs(c[1]-c[2]);if(cnt==3)return min(abs(c[1]-c[2])+abs(c[2]-c[3]),abs(c[1]-(m-c[2]+1))+abs(m-c[2]+1-c[3]));int ret=cal(c[1],c[cnt],c[2],c[cnt-1]);ret=min(ret,cal(c[1],c[cnt],m-c[2]+1,m-c[cnt-1]+1));for(i=3;i<cnt;i++){ret=min(ret,cal(c[1],c[cnt],c[2],m-c[i]+1));ret=min(ret,cal(c[1],c[cnt],m-c[2]+1,c[i]));}return ret;
}
int main(){scanf("%d%d",&n,&m);n++;scanf("%d%d",&b[1],&b[n]);a[1]=a[n]=1;for(i=2;i<n;i++)scanf("%d%d",&a[i],&b[i]);for(i=1,j=0;i<=n;i++)if(a[i]==1){if(j)ans+=solve(j,i);j=i;}printf("%d",ans);
}
/*
5 8
2 6
1 7
2 3
1 1
2 15 21
4 15
2 5
2 6
1 2
2 210 10
1 10
2 2
2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 10
*/

  

I. Minimum Prefix

二分答案,然后Hopcroft求二分图最大匹配检验。

J. Terminal

$f[i][j]$表示考虑前$i$组,第一辆车上了$j$个人是否可行。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int n, m, K;
int a[N];
int cnt[N], tmp[N];
bitset<N>f[2020];
int main()
{while(~scanf("%d%d%d", &n, &m, &K)){gmin(K, n);MS(cnt, 0);MS(tmp, 0);for(int i = 1; i <= n; ++i){scanf("%d", &a[i]);++cnt[a[i]];}f[0][0] = 1;int g = 0;LL ans = 1e18;for(int i = 1; i <= n; ++i){++tmp[a[i]];if(tmp[a[i]] == cnt[a[i]]){++g;f[g] = f[g - 1] | (f[g - 1] << cnt[a[i]]);for(int j = 1; j <= K; ++j)if(f[g][j] && n - j <= K){gmin(ans, (LL)i * j + (LL)n * (n - j));}}}if(ans == 1e18)ans = -1;printf("%lld\n", ans);}return 0;
}
/*
【trick&&吐槽】【题意】【分析】【时间复杂度&&优化】*/

  

K. New Tetris

用线段树加速模拟即可。

L. Canonical duel

每个炮塔可以将其同行同列的所有炮塔都激活,因此枚举一个点,然后将上下左右两个连通块合并即可。

#include<cstdio>
const int N=2010,M=N*N;
int n,m,i,j,k,id[N][N],cnt,f[M],size[M];
int ans=-1,px,py;
char a[N][N];
int left[N][N],right[N][N],up[N][N],down[N][N];
int F(int x){return f[x]==x?x:f[x]=F(f[x]);}
inline void merge(int x,int y){x=F(x),y=F(y);if(x==y)return;f[x]=y;
}
inline void gao(int x,int y){int A=up[x][y];if(!A)A=down[x][y];int B=left[x][y];if(!B)B=right[x][y];int ret=size[f[A]];if(f[A]!=f[B])ret+=size[f[B]];if(ret>ans)ans=ret,px=x,py=y;
}
int main(){scanf("%d%d",&n,&m);for(i=1;i<=n;i++)scanf("%s",a[i]+1);for(i=1;i<=n;i++)for(j=1;j<=m;j++)a[i][j]=a[i][j]=='+';for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(a[i][j]){id[i][j]=++cnt;f[cnt]=cnt;}for(i=1;i<=n;i++)for(j=1;j<=m;j++){left[i][j]=a[i][j]?id[i][j]:left[i][j-1];up[i][j]=a[i][j]?id[i][j]:up[i-1][j];}for(i=n;i;i--)for(j=m;j;j--){right[i][j]=a[i][j]?id[i][j]:right[i][j+1];down[i][j]=a[i][j]?id[i][j]:down[i+1][j];}for(i=1;i<=n;i++){k=0;for(j=1;j<=m;j++)if(a[i][j]){if(k)merge(k,id[i][j]);k=id[i][j];}}for(i=1;i<=m;i++){k=0;for(j=1;j<=n;j++)if(a[j][i]){if(k)merge(k,id[j][i]);k=id[j][i];}}for(i=1;i<=cnt;i++)size[F(i)]++;for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(!a[i][j])gao(i,j);if(ans<=0)puts("0");else printf("%d\n%d %d",ans,px,py);
}

  

转载于:https://www.cnblogs.com/clrs97/p/7669673.html

XVII Open Cup named after E.V. Pankratiev. GP of Tatarstan相关推荐

  1. XIV Open Cup named after E.V. Pankratiev. GP of Europe

    A. The Motorway 等价于找到最小和最大的$L$满足存在$S$使得$S+(i-1)L\leq a_i\leq S+i\times L$ 即 $S\leq\min((1-i)L+a_i)$ ...

  2. XVI Open Cup named after E.V. Pankratiev. GP of Ekaterinburg

    A. Avengers, The 留坑. B. Black Widow 将所有数的所有约数插入set,然后求mex. #include<bits/stdc++.h> using names ...

  3. XII Open Cup named after E.V. Pankratiev. GP of Eastern Europe (AMPPZ-2012)

    A. Automat $m$超过$1600$是没用的. 从后往前考虑,设$f[i][j][k]$表示考虑$[i,n]$这些物品,一共花费$j$元钱,买了$k$个物品的最大收益. 时间复杂度$O(n^5 ...

  4. XVIII Open Cup named after E.V. Pankratiev. GP of Urals

    A. Nutella's Life 斜率优化DP显然,CDQ分治后按$a$排序建线段树,每层维护凸包,查询时不断将队首弹出即可. 时间复杂度$O(n\log^2n)$. #include<cst ...

  5. XVI Open Cup named after E.V. Pankratiev. GP of Eurasia

    A. Nanoassembly 首先用叉积判断是否在指定向量右侧,然后解出法线与给定直线的交点,再关于交点对称即可. #include<bits/stdc++.h> using names ...

  6. XIII Open Cup named after E.V. Pankratiev. GP of Ukraine

    A. Automaton 后缀自动机可以得到$O(2n+1)$个状态,但是后缀自动机会拒绝接收所有不是$S$的子串的串,所以在建立后缀自动机的时候不复制节点即可得到$n+1$个状态的DFA. #inc ...

  7. XVI Open Cup named after E.V. Pankratiev. GP of Siberia

    A. Passage 枚举两个点,看看删掉之后剩下的图是否是二分图. #include <bits/stdc++.h> using namespace std ;const int MAX ...

  8. XVI Open Cup named after E.V. Pankratiev. GP of SPB

    A. Bubbles 枚举两个点,求出垂直平分线与$x$轴的交点,答案=交点数+1. 时间复杂度$O(n^2\log n)$. #include<cstdio> #include<a ...

  9. XV Open Cup named after E.V. Pankratiev. GP of Siberia-Swimming

    给出两个点,找到过这两个点的等角螺线,并求出中间的螺线长 $c = \frac{b}{a}$ $p = a \times c^{\frac{\theta}{angle}}$ 对弧线积分 #includ ...

最新文章

  1. 【细无巨细,包你学会】自学Python运行时会遇到的异常与解决方法
  2. shell脚本分析mysql慢查询日志(slow log)
  3. oracle1537,dataguard 出现ORA-16136错误
  4. 【Guava】使用Guava的RateLimiter做限流
  5. 【译】BINDER - ANALYSIS AND EXPLOITATION OF CVE-2020-0041
  6. [剑指offer][JAVA]面试题第[11]题[旋转数组的最小数字][二分法][分治]
  7. ubuntu安装proxychains及自动补全
  8. linux grep命令参数及用法详解---linux管道命令grep
  9. 关于umask函数和creat函数
  10. 企业网络管理利器-SpiceWorks(1)
  11. css中关于单行文本溢出部分用省略号显示
  12. oracle表同步 job,Oracle中通过Job实现定时同步两个数据表之间的数据
  13. 【NOIP2017提高A组冲刺11.2】救赎(数学期望)
  14. 不限专业和工作年限就能报考的证书有哪些?
  15. 关闭Chrome启动时的360导航页面
  16. calico源码分析-ipam(1)
  17. 用*打印一个长方形.
  18. shp文件导入postgresql数据库
  19. Java支付宝APP支付-验证异步通知消息
  20. 如何删除电脑里的android驱动程序,【教程】安卓手机系统自带程序卸载

热门文章

  1. linux网络的高可用性,构建高可用性网络
  2. 安徽大学计算机教学平台c语言作业,安徽大学计算机基础C语言选择题
  3. python客户价值分析_[Python数据挖掘]第7章、航空公司客户价值分析
  4. python制作中秋贺卡_中秋节到了,送你一个Python做的Crossin牌“月饼”
  5. C 语言的标准输入对象是,《面向对象程序设计C+》期末试卷及标准答案
  6. comparator比较器用法_Python学习:好像很少人知道 Python iter() 的另外一个用法?...
  7. linux 限制连接时间,linux抵御DDoS攻击方法 通过iptables限制TCP连接和频率
  8. cpu风扇一会转一会停_空调维修|空调开机一会就停显示e1|空调维修方法
  9. jupyter下使用conda环境
  10. 深入理解javascript原型和闭包(3)——prototype原型