Weekly Traning Farm 16
先安利一下这套比赛,大概是doreamon搞的,每周五晚上有一场,虽然没人做题目质量挺高的 http://codeforces.com/group/gRkn7bDfsN/contests(报名前要先报名group,不用审核) 每一次的题解可以在这里看到 http://dreamoon4.blogspot.tw/(梯子自备)
这场是http://codeforces.com/group/gRkn7bDfsN/contest/210418
这一场是类似之前某一场cf把每题拆成几个数据规模的题目分别给分。之前连续出了两三场乱七八糟的构造题
A Apple Pen
给出n个字符串和一个母串,问这个母串能用多少种方式从n个字符串中选2个拼成并输出方案(可以假装方案不是很多)。2<=n<=10^6,字符串总长<=2e7,母串长度<=1e6。

喜闻乐见的样例。
这个题十分菜啊,假装每个字符串分别为前缀或者后缀判断是否可行,然后合在一起输出。之前脑子里进水了想了一堆奥妙重重的做法
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
#define fi first
#define se second
#define fe first
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define Edg int M=0,fst[SZ],vb[SZ],nxt[SZ];void ad_de(int a,int b){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;}void adde(int a,int b){ad_de(a,b);ad_de(b,a);}
#define Edgc int M=0,fst[SZ],vb[SZ],nxt[SZ],vc[SZ];void ad_de(int a,int b,int c){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;vc[M]=c;}void adde(int a,int b,int c){ad_de(a,b,c);ad_de(b,a,c);}
#define es(x,e) (int e=fst[x];e;e=nxt[e])
#define esb(x,e,b) (int e=fst[x],b=vb[e];e;e=nxt[e],b=vb[e])
#define VIZ {printf("digraph G{\n"); for(int i=1;i<=n;i++) for es(i,e) printf("%d->%d;\n",i,vb[e]); puts("}");}
#define VIZ2 {printf("graph G{\n"); for(int i=1;i<=n;i++) for es(i,e) if(vb[e]>=i)printf("%d--%d;\n",i,vb[e]); puts("}");}
#define SZ 1234567
int n;
string s[1000007];
string t;
char tmp[20000007];
vector<int> vs[1234567],vs2[1234567];
vector<pii> rst;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",tmp); s[i]=tmp;
}
scanf("%s",tmp); t=tmp;
for(int i=1;i<=n;i++)
{
if(s[i].length()>t.length()) continue;
if(t.substr(0,s[i].length())==s[i])
vs[s[i].length()].pb(i);
if(t.substr(t.length()-s[i].length(),s[i].length())==s[i])
vs2[t.length()-s[i].length()].pb(i);
}
for(int i=0;i<t.length();i++)
{
for(auto a:vs[i])
{
for(auto b:vs2[i])
{
if(a==b) continue;
rst.pb(pii(min(a,b),max(a,b)));
}
}
}
sort(rst.begin(),rst.end());
rst.erase(unique(rst.begin(),rst.end()),rst.end());
printf("%d\n",rst.size());
for(int i=0;i<rst.size();i++) printf("%d %d\n",rst[i].fi,rst[i].se);
}
B Two Swords
有n把剑,有20种属性,每把可能会有或无每种属性,询问q次,每次要求找出两把剑,每种要求的属性至少要有一把剑具有,问找出这两把剑的方案数。n,q<=50W。
大概是个fwt/集合幂级数的裸题。
首先我们先把每种属性是否具有当做一个二进制数,拿个数组存下来每个二进制数出现的次数,就叫数组x好了。
那我们第一步就是要求
for(int i=0;i<(1<<20);i++)
for(int j=0;j<(1<<20);j++)
a[i|j]+=x[i]*x[j];
从fwt的角度理解:这就是个or的fwt,直接用fwt水~ http://picks.logdown.com/posts/179290-fast-walsh-hadamard-transform(我当时比赛时就是这么想的...)
从集合幂级数的角度理解:这就是个集合并卷积,我们可以用经典的快速莫比乌斯变换+快速莫比乌斯反演来做。(似乎ysy和出题人都是这么想的)
其实这两个做法只是同一个东西的两种写法...
这个数组求出来之后我们可以求出或恰好为一个数的方案数,但是题目中询问对不要求的属性不作要求,然后我们可以把每一位反过来,再用一发快速莫比乌斯变换。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
#define fi first
#define se second
#define fe first
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define Edg int M=0,fst[SZ],vb[SZ],nxt[SZ];void ad_de(int a,int b){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;}void adde(int a,int b){ad_de(a,b);ad_de(b,a);}
#define Edgc int M=0,fst[SZ],vb[SZ],nxt[SZ],vc[SZ];void ad_de(int a,int b,int c){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;vc[M]=c;}void adde(int a,int b,int c){ad_de(a,b,c);ad_de(b,a,c);}
#define es(x,e) (int e=fst[x];e;e=nxt[e])
#define esb(x,e,b) (int e=fst[x],b=vb[e];e;e=nxt[e],b=vb[e])
#define VIZ {printf("digraph G{\n"); for(int i=1;i<=n;i++) for es(i,e) printf("%d->%d;\n",i,vb[e]); puts("}");}
#define VIZ2 {printf("graph G{\n"); for(int i=1;i<=n;i++) for es(i,e) if(vb[e]>=i)printf("%d--%d;\n",i,vb[e]); puts("}");}
#define SZ 666666
int mx=(1<<20);
int n,q;
ll cnt[2333333],qwq[2333333],inv[2333333];
char s[233];
int toi(char* s)
{
int x=0;
for(int i=0;s[i];i++) x=x*2+s[i]-48;
return x;
}
void trans(ll* g,int k)
{
for(int i=0;i<20;i++)
{
int all=(mx-1)^(1<<i);
for(int s=0;s<mx;s++)
{
if((s&all)!=s) continue;
g[s^(1<<i)]+=g[s]*k;
}
}
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
++cnt[toi(s)];
}
for(int i=0;i<mx;i++) qwq[i]=cnt[i];
trans(cnt,1);
for(int i=0;i<mx;i++) cnt[i]*=cnt[i];
trans(cnt,-1);
for(int i=0;i<mx;i++) inv[(mx-1)^i]=(cnt[i]-qwq[i])/2;
trans(inv,1);
while(q--)
{
scanf("%s",s);
int x=toi(s);
printf("%I64d\n",inv[(mx-1)^x]);
}
}
代码十分简洁明了。当然你可以把trans换成分治fwt效果是一样的= =
C Zekken
有一条数轴,你开始在0的位置,每单位时间你至多能移动d个单位,在ti时刻xi位置会出现一个宝物,然后马上消失,只有ti时刻你站在xi位置才能捡到。问最多你能捡到几个宝物。宝物数量n<=50W,没有ti、xi都相等的宝物。
先说结论,把一个点换成(ti*d-xi,ti*d+xi),如果有任一维<0就忽略这个点,否则将一维排序另一维lis即为答案。
我们先考虑d=1的情况,对于d≠1的显然只要把一秒续成d秒就行了(即ti*=d)。
我们考虑把(xi,ti)当做一个点,显然下一个点只能在左右45°内

我们往右转45°就变成了要在这个点的右上方,(a,b)右转45°就成了((a+b)/sqrt(2),(b-a)/sqrt(2)),我们忽略那个sqrt(2),(xi,ti)转完就相当于(xi+ti,ti-xi)。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
#define fi first
#define se second
#define fe first
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define Edg int M=0,fst[SZ],vb[SZ],nxt[SZ];void ad_de(int a,int b){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;}void adde(int a,int b){ad_de(a,b);ad_de(b,a);}
#define Edgc int M=0,fst[SZ],vb[SZ],nxt[SZ],vc[SZ];void ad_de(int a,int b,int c){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;vc[M]=c;}void adde(int a,int b,int c){ad_de(a,b,c);ad_de(b,a,c);}
#define es(x,e) (int e=fst[x];e;e=nxt[e])
#define esb(x,e,b) (int e=fst[x],b=vb[e];e;e=nxt[e],b=vb[e])
#define VIZ {printf("digraph G{\n"); for(int i=1;i<=n;i++) for es(i,e) printf("%d->%d;\n",i,vb[e]); puts("}");}
#define VIZ2 {printf("graph G{\n"); for(int i=1;i<=n;i++) for es(i,e) if(vb[e]>=i)printf("%d--%d;\n",i,vb[e]); puts("}");}
#define SZ 666666
typedef pair<ll,ll> pll;
int n,d,x[SZ],t[SZ],bs[SZ],dp[SZ];
ll gg[SZ],tmp[SZ];
pll ps[SZ];
int mx(int g)
{
int ans=0;
for(;g>=1;g-=g&-g) ans=max(ans,bs[g]);
return ans;
}
void edt(int x,int y)
{
for(;x<=n;x+=x&-x) bs[x]=max(bs[x],y);
}
int main()
{
scanf("%d%d",&n,&d);
for(int i=1;i<=n;i++)
{
scanf("%d%d",x+i,t+i);
ps[i]=pll(t[i]*(ll)d-x[i],t[i]*(ll)d+x[i]);
if(ps[i].fi<0||ps[i].se<0)
{
--i; --n; continue;
}
}
sort(ps+1,ps+1+n);
for(int i=1;i<=n;i++) gg[i]=ps[i].se;
for(int i=1;i<=n;i++) tmp[i]=gg[i];
sort(tmp+1,tmp+1+n);
int ans=0;
for(int i=1;i<=n;i++)
{
gg[i]=(lower_bound(tmp+1,tmp+1+n,gg[i])-tmp);
dp[i]=mx(gg[i])+1; edt(gg[i],dp[i]);
ans=max(ans,dp[i]);
}
printf("%d\n",ans);
}
Weekly Traning Farm 16的更多相关文章
- SharePoint 解决方案和功能-PowerShell
1. 添加解决方案到SharePoint场 Add-SPSolution "c:\newsolution.wsp" 2. 获取场中的解决方案 Get-SPSolution 3. 获 ...
- CI Weekly #16 | 从另一个角度看开发效率:flow.ci 数据统计功能上线
很开心的告诉大家,flow.ci 数据统计功能已正式上线. 进入 flow.ci 控制台,点击「数据分析」按钮,你可以按照时间日期筛选,flow.ci 将多维度地展示「组织与项目」的构建数据指标与模型 ...
- Murano Weekly Meeting 2016.08.16
Meeting time: 2016.August.16 1:00~2:00 Chairperson: Kirill Zaitsev, from Mirantis Meeting summary: ...
- CI Weekly #6 | 再谈 Docker / CI / CD 实践经验
CI Weekly 围绕『 软件工程效率提升』 进行一系列技术内容分享,包括国内外持续集成.持续交付,持续部署.自动化测试. DevOps 等实践教程.工具与资源,以及一些工程师文化相关的程序员 Ti ...
- fir.im Weekly - 揭秘 iOS 面向协议编程
本期 fir.im Weekly 重点推荐关于 iOS 面向协议编程相关文章,还有 iOS 多线程安全.Swift 进阶.Android MVVM 应用框架.Android 蓝牙实践等技术文章分享和工 ...
- How To Collect ULS Log from SharePoint Farm
We can use below command to collect SharePoint ULS log from all servers in the Farm in PowerShell. M ...
- fir.im Weekly - 这是一份强大的 SwiftGuide
大新闻!Apple 10 亿美元融资滴滴!库克大叔对中国 iOS 开发者表达了高度认可,同时也传出 iOS 10 将内置滴滴 App 的消息.想像下,某个加班的深夜飙完代码,最性感的事情莫过于:「Si ...
- fir.im Weekly - Stanford 的 Swift 课程来了
上周提过,Swift 的 Github 主页上已经有了 >>「Port to Android」,这周重点推荐一下 Stanford 的 Swift 课程. Developing iOS 9 ...
- fir.im Weekly - 论个人技术影响力是如何炼成的
每个圈子都有一群能力强且懂得经营自己的人,技术圈也是如此.本期 fir.im Weekly 一如往期精选了一些实用的 iOS,Android 开发工具和源码分享,还有一些关于程序员的成长 Tips 和 ...
随机推荐
- EntityFramework.Extended 实现 update count+=1
在使用 EF 的时候,EntityFramework.Extended 的作用:使IQueryable<T>转换为update table set ...,这样使我们在修改实体对象的时候, ...
- abstract与interface之房祖名张默版
最近把java基础知识拿出来看看,看到abstract与interface的时候,觉得有点模糊,好像面试官也喜欢问这个问题.我在百度了查了好长时间,觉得讲算比较清楚的是那篇讲 Door,然后想要带个报 ...
- Runtime应用防止按钮连续点击 (转)
好久之前就看到过使用Runtime解决按钮的连续点击的问题,一直觉得没啥好记录的.刚好今天旁边同时碰到这个问题,看他们好捉急而且好像很难处理,于是我先自己看看… 前面自己也学习了很多Runtime的东 ...
- mailto实现将用户在网页中输入的内容传递到本地邮件客户端
背景: 想在自己的网站中有这样一个设计: 用户点击提交按钮之后,就会打开本地邮件客户端,并自动将他在输入框中输入的内容作为邮件的内容,像下面这样: mailto可以帮助实现这个功能. 简介: mail ...
- java netty socket库和自定义C#socket库利用protobuf进行通信完整实例
之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ...
- Basic Tutorials of Redis(8) -Transaction
Data play an important part in our project,how can we ensure correctness of the data and prevent the ...
- ETL数据从sqlserver到mysql之间迁移
因近期需要进行sqlserver数据到mysql之间的数据同步.偶然之间发现了这一款工具ELK 一.下载 1.Kettle可以在http://kettle.pentaho.org/网站下载 2.下载的 ...
- [Asp.net 5] Caching-缓存预告
本节讲Asp.net 5的缓冲.解决方案可以通过网址:https://github.com/aspnet/Caching下载 也是Asp.net 5开源代码介绍的第6部分,前5部分链接如下: 1. D ...
- 【设计模式】单例模式 c++实现
单例模式一般应用在整个应用中只会存在一个对象.比如应用类,游戏场景类,工具类等. 实现方式: 头文件 singleton.h: #ifndef _SINGLETON_H_ #define _SINGL ...
- 使用tomcat manager 管理和部署项目
在部署tomcat项目的时候,除了把war文件直接拷贝到tomcat的webapp目录下,还有一种方法可以浏览器中管理和部署项目,那就是使用tomcat manager. 默认情况下,tomcat m ...