赛后总结:
1.补字符串
2.前期交题看三遍
3.认真听取zcz兄弟的意见 最后时间该冲的时候就要冲
A.分情况讨论一下 K > 2先手必胜
N可能是0
solved by gbs
00:17:41(-2) 没有考虑0 WA2发
#include <iostream>
#include<stack>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<ctime>
#include<complex>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<deque>
using namespace std;
typedef long long LL;
int main()
{
int n,k;
while(cin >>n >>k)
{
if (n == 0)
{
printf("Austin\n");
}
else if (k ==1)
{
if (n&1)
printf("Adrien\n");
else
printf("Austin\n");
}
else
{
printf("Adrien\n");
}
}
return 0;
}
D.经典的最小球覆盖问题,方法一般分为三分套三分套三分或者随机算法
网络上有很多类似的解法,就不赘述了
solved by hl
0:41:43
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <bitset>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x)
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x)
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double PI = acos(-1.0);
const double eps = 1e-9;
const int maxn = 110;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int N,M,K;
struct Point{
double x,y,z;
Point(){}
Point(double x,double y,double z):x(x),y(y),z(z){}
}point[maxn],ans;
double A;
double ansx,ansy;
const double delta = 0.999;
double check(double x,double y,double z){
double t = 0;
for(int i = 1; i <= N ; i ++){
double d = (x - point[i].x) * (x - point[i].x) + (y - point[i].y) * (y - point[i].y) + (z - point[i].z) * (z - point[i].z);
d = sqrt(d);
t = max(d,t);
}
return t;
}
void sa(){
double t = 3000;
Point a = ans;
while(t > 1e-18){
Point anstmp = a;
anstmp.x += (rand() * 2 - RAND_MAX) * t;
anstmp.y += (rand() * 2 - RAND_MAX) * t;
anstmp.z += (rand() * 2 - RAND_MAX) * t;
double newans = check(anstmp.x,anstmp.y,anstmp.z);
double DE = newans - A;
if(DE < 0){
ans = a = anstmp;
A = newans;
}else if(exp(-DE / t) * RAND_MAX > rand()){
a = anstmp;
}
t = t * delta;
}
}
void SA(){
sa(); sa(); sa();
sa(); sa(); sa();
}
int main(){
Sca(N); srand(time(NULL));
for(int i = 1; i <= N ; i ++){
scanf("%lf%lf%lf",&point[i].x,&point[i].y,&point[i].z);
ans.x += point[i].x; ans.y += point[i].y; ans.z += point[i].z;
}
ans.x /= N; ans.y /= N; ans.z /= N;
A = check(ans.x,ans.y,ans.z);
//cout << A << endl;
//cout << ans.x << " " << ans.y << " " << ans.z <<endl;
SA();
printf("%.15lf",A);
return 0;
}
G.数学功底强的直接把式子推出来
不想推式子的证明他的式子是一个4次以下的多项式 然后拉格朗日插值
solved by gbs
1:49:51(-3)
参数没调好TLE + RE
#include <iostream>
#include<stack>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<ctime>
#include<complex>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<deque>
using namespace std;
typedef long long LL;
const int mod =1e9+7;
LL ans ;
LL qpow(LL a,int k){
LL ans =1;
while(k!=0)
{
if (k&1)ans =(ans*a)%mod;
a= (a*a)%mod;
k/=2;
}
return ans;
}
int xn[6];
int yna[6];
int hn[6];
int sizea= 5;
int main()
{
//LL inv6=qpow(6,mod-2);
int inv[45];
yna[1] =1;
yna[2] = 5;
yna[3] = 15;
yna[4] = 35;
yna[5] = 70;
for (int i=1; i<=35; i++)
inv[i] =qpow(i-10,mod-2);
int t;
int n;
cin>>t;
for (int i=1; i<=5; i++)
{
LL llans = 1;
for (int j =1; j<=5; j++)
{
if (j == i)continue;
llans = ((llans *inv[i-j+10])%mod+mod)%mod;
}
hn[i] = llans;
}
while(t--)
{
scanf("%d",&n);
LL ans = 0;
for (int i=1; i<=5; i++)
{
LL llans = 1;
for (int j =1; j<=5; j++)
{
if (j == i)continue;
llans = ((llans *(n-j))%mod+mod)%mod;
}
llans =(llans*hn[i])%mod;
//cout<<llans<<endl;
ans = (ans+llans*yna[i])%mod;
}
printf("%lld\n",ans);
/*ans = n;
ans =(ans*(n+1))%mod;
ans =(ans*(2LL*n+1))%mod;
ans =(ans*i)%mod;*/
}
return 0;
}
I.似乎是个最大流模型
不过似乎也有非网络流做法。
将每个hero对每个monster连接一条容量为1的边,然后源点对每个hero连接一条容量为1的边,monster对汇点连1的边。
然后源点连出一个点作为魔药,容量为K,魔药点对每个hero连接一条容量为1的边
solved by hl
1:04:51
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <bitset>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x)
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x)
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double PI = acos(-1.0);
const double eps = 1e-9;
const int maxn = 1210;
const int maxm = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int N,M,K;
struct Dinic{
struct Edge{
int from,to,next,cap,flow;
Edge(){}
Edge(int from,int to,int next,int cap,int flow):from(from),to(to),next(next),cap(cap),flow(flow){}
}edge[maxm * 2];
int n,s,t,head[maxn],tot;
int dep[maxn],cur[maxn];
void init(int n,int s,int t){
this->n = n; this->s = s; this->t = t;
tot = 0;
for(int i = 0 ; i <= n ; i ++) head[i] = -1;
}
inline void add(int s,int t,int w){
// cout << s << " " << t << " " << w <<endl;
edge[tot] = Edge(s,t,head[s],w,0);
head[s] = tot++;
edge[tot] = Edge(t,s,head[t],0,0);
head[t] = tot++;
}
inline bool BFS(){
for(int i = 0 ; i <= n ; i ++) dep[i] = -1;
dep[s] = 1;
queue<int>Q; Q.push(s);
while(!Q.empty()){
int u = Q.front(); Q.pop();
for(int i = head[u]; ~i ; i = edge[i].next){
int v = edge[i].to;
//cout <<edge[i].flow << " " << edge[i]
//cout << v << " " << dep[v] << endl;
if(~dep[v] || edge[i].flow >= edge[i].cap) continue;
dep[v] = dep[u] + 1;
Q.push(v);
}
}
return ~dep[t];
}
inline int DFS(const int& u,int a){
if(u == t || !a) return a;
int flow = 0;
for(int &i = cur[u]; ~i; i = edge[i].next){
int v = edge[i].to;
if(dep[v] != dep[u] +1) continue;
int f = DFS(v,min(a,edge[i].cap - edge[i].flow));
if(!f) continue;
edge[i ^ 1].flow -= f;
edge[i].flow += f;
a -= f;
flow += f;
}
return flow;
}
inline int maxflow(){
return maxflow(s,t);
}
inline int maxflow(int s,int t){
int flow = 0;
while(BFS()){
//cout << "bug" <<endl;
for(int i = 0 ; i <= n ; i ++) cur[i] = head[i];
flow += DFS(s,INF);
}
return flow;
}
}g;
int main(){
Sca3(N,M,K);
int S= N + M + 3,T = N + M + 4;
g.init(T,S,T);
g.add(S,N + M + 1,INF);
g.add(S,N + M + 2,K);
for(int i = 1; i <= N ; i ++){
g.add(N + M + 1,M + i,1);
g.add(N + M + 2,M + i,1);
}
for(int i = 1; i <= M ; i ++) g.add(i,T,1);
for(int i = 1; i <= N ; i ++){
int k = read();
while(k--){
int x = read();
g.add(M + i,x,1);
}
}
Pri(g.maxflow());
return 0;
}
J.
当仅考虑素数的时候,当一个点i含素数因子时,对答案产生的贡献是(i + 1) * (N - i + 1),即包括这个点的所有范围都会出现这个素数,每个范围产生1的贡献,总贡献就是范围的个数
所以说我们用素数筛预处理出每个数含有的所有素数因子,对于每一个素数因子,出现的时候都会产生以上的贡献。
剩下的就是考虑出现相同的素数重复计算的部分了
形如 2 1 1 2 1 1 2 1 1 1的样例
素数2的下标为1 4 7
素数2产生的贡献应当是(1 - 0) * (10 - 1 + 1) + (4 - 1) * (10 - 4 + 1) + (7 - 4) * (10 - 7 + 1)
所以还需要一个数组记录每个素数当前出现的最右端的位置
solved by hl
0:25:30 (-1)
运算过程中爆LL WA一发
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <bitset>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x)
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x)
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double PI = acos(-1.0);
const double eps = 1e-9;
const int maxn = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int N,M,K;
int a[maxn];
vector<int>prime[maxn];
int isprime[maxn];
void init(){
for(int i = 2; i < maxn; i ++) isprime[i] = 1;
for(int i = 2; i < maxn; i ++){
if(!isprime[i]) continue;
prime[i].pb(i);
for(int j = i + i; j < maxn; j += i){
isprime[j] = 0;
prime[j].pb(i);
}
}
}
LL pos[maxn];
int main(){
Sca(N); init();
LL ans = 0;
for(LL i = 1; i <= N ; i ++){
Sca(a[i]);
for(int j = 0 ; j < prime[a[i]].size(); j ++){
int v = prime[a[i]][j];
ans += 1ll * (i - pos[v]) * (N - i + 1);
pos[v] = i;
}
}
Prl(ans);
return 0;
}
K.
用脑子想策略 (×)
随机盲一发 (√)
在这些奇怪的类似构造题上 就要想一些奇怪的方法。
unsolved by gbs
M.
应该是manacher计算回文串的贡献 + 计算LCP
写了AC自动机最后发现爆时间复杂度
unsolved by hl
来源:oschina
链接:https://my.oschina.net/u/4336234/blog/3441090