solo打得头皮发麻。一个下午全在贴板,药丸。
A
折半一下,前缀最值搞搞就完了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int w[40][4],v[40];
int m[4];
struct node{
ll sta,sum;
void init(){
sta=sum=0;
}
}dp[37][37][37][37];
bool operator<(const node& a,const node& b){
return a.sum<b.sum;
}
inline void gmax(node& a,node b){
a=max(a,b);
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
for(int j=0;j<4;j++)scanf("%d",&w[i][j]);
scanf("%d",&v[i]);
}
for(int i=0;i<4;i++)scanf("%d",&m[i]);
int l=n/2;
int r=n-l;
for(int st=0;st<(1<<r);st++){
int x=0,y=0,z=0,p=0,sum=0;
for(int i=0;i<r;i++){
if(st&(1<<i)){
x+=w[i+l][0];
y+=w[i+l][1];
z+=w[i+l][2];
p+=w[i+l][3];
sum+=v[i+l];
}
}
if(x<=m[0]&&y<=m[1]&&z<=m[2]&&p<=m[3]){
gmax(dp[x][y][z][p],(node){st,sum});
}
}
for(int x=0;x<=m[0];x++){
for(int y=0;y<=m[1];y++){
for(int z=0;z<=m[2];z++){
for(int p=0;p<=m[3];p++){
if(x>0)gmax(dp[x][y][z][p],dp[x-1][y][z][p]);
if(y>0)gmax(dp[x][y][z][p],dp[x][y-1][z][p]);
if(z>0)gmax(dp[x][y][z][p],dp[x][y][z-1][p]);
if(p>0)gmax(dp[x][y][z][p],dp[x][y][z][p-1]);
}
}
}
}
node ans;
ans.init();
for(int st=0;st<(1<<l);st++){
int x=0,y=0,z=0,p=0,sum=0;
for(int i=0;i<l;i++){
if(st&(1<<i)){
x+=w[i][0];
y+=w[i][1];
z+=w[i][2];
p+=w[i][3];
sum+=v[i];
}
}
if(x<=m[0]&&y<=m[1]&&z<=m[2]&&p<=m[3]){
node rev=dp[m[0]-x][m[1]-y][m[2]-z][m[3]-p];
gmax(ans,(node){(rev.sta<<l)+st,rev.sum+sum});
}
}
vector<int>vs;
ll st=ans.sta;
for(int i=0;i<n;i++){
if(st&(1ll<<i)){
vs.push_back(i);
}
}
printf("%d\n",vs.size());
for(int i=0;i<vs.size();i++){
printf("%d%c",vs[i],i==vs.size()-1?'\n':' ');
}
}
C
度了个区间切割的板贴了上去。
#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#define maxn 330000+20
using namespace std;
int n,q;
int cnt=0;
struct node
{
node *f;
node *ch[2];
int size;
int lazy;
int id;
}S[maxn];
node *root;
void pushdown(node *u)
{
if((!u->lazy)||(u==NULL))return ;
if(u->ch[0]!=NULL)u->ch[0]->lazy^=1;
if(u->ch[1]!=NULL)u->ch[1]->lazy^=1;
node *y=u->ch[0];
u->ch[0]=u->ch[1];
u->ch[1]=y;
u->lazy=0;
}
void pushup(node *u)
{
u->size=1;
if(u->ch[0]!=NULL)u->size+=u->ch[0]->size;
if(u->ch[1]!=NULL)u->size+=u->ch[1]->size;
}
void rotate(node *u)
{
node *f=u->f;
if(f==NULL)return ;
pushdown(u);
pushdown(f);
node *ff=f->f;
int d=u==f->ch[1];
int dd=0;
if(ff!=NULL)dd=f==ff->ch[1];
if(u->ch[d^1])u->ch[d^1]->f=f;
f->ch[d]=u->ch[d^1];
/*int size=u->size;
u->size=f->size;
f->size=f->size-size;
if(u->ch[d^1]!=NULL)f->size+=u->ch[d^1]->size;
*/
f->f=u;
u->ch[d^1]=f;
if(ff!=NULL)ff->ch[dd]=u;
u->f=ff;
pushup(f);
pushup(u);
}
void splay(node *u,node *p)
{
pushdown(u);
while(u->f!=p)
{
node *f=u->f;
node *ff=f->f;
if(ff==p)
{
rotate(u);
break;
}
int d=u==f->ch[1];
int dd=f==ff->ch[1];
if(d==dd)rotate(f);
else rotate(u);
rotate(u);
}
pushup(u);
if(p==NULL)root=u;
}
void insert(int id)
{
if(root==NULL)
{
node *y=&S[++cnt];
y->id=id;
y->size=1;
y->ch[0]=NULL;
y->ch[1]=NULL;
y->f=NULL;
y->lazy=0;
root=y;
return ;
}
node *u=root;
node *y;
while(1)
{
u->size++;
if(id<u->id)
{
//左边
if(u->ch[0]!=NULL)u=u->ch[0];
else
{
y=&S[++cnt];
y->id=id;
y->size=1;
y->ch[0]=NULL;
y->ch[1]=NULL;
y->f=u;
u->ch[0]=y;
y->lazy=0;
break;
}
}
else
{
if(u->ch[1]!=NULL)u=u->ch[1];
else
{
y=&S[++cnt];
y->id=id;
y->size=1;
y->ch[0]=NULL;
y->ch[1]=NULL;
y->f=u;
u->ch[1]=y;
y->lazy=0;
break;
}
}
}
splay(y,NULL);
}
char s[10];
node *find (int x)
{
node *u=root;
while(1)
{
int xx=1;
if(u->ch[0]!=NULL)xx+=u->ch[0]->size;
if(xx==x)return u;
if(x<xx)u=u->ch[0];
else
{
x-=xx;
u=u->ch[1];
}
}
}
void cut(int l,int r,int c)
{
node *x=find(l);
node *y=find(r+2);
splay(x,NULL);
splay(y,root);
node *u=root->ch[1]->ch[0];
/*root->size-=u->size;
root->ch[1]->size-=u->size;
*/
root->ch[1]->ch[0]=NULL;
pushup(root->ch[1]);
pushup(root);
//u->f=NULL;
node *yy=find(c+1);
splay(yy,NULL);
node *xx=find(c+2);
splay(xx,root);
//插入
root->ch[1]->ch[0]=u;
u->f=root->ch[1];
//root->ch[1]->size+=u->size;
//root->size+=u->size;
pushup(root->ch[1]);
pushup(root);
}
void flip(int l,int r)
{
node *x=find(l);
node *y=find(r+2);
splay(x,NULL);
splay(y,root);
node *u=root->ch[1]->ch[0];
u->lazy^=1;
}
void dfs(node *u)
{
//printf("debug : %d %d\n",u->size,u->id);
pushdown(u);
if(u->ch[0])dfs(u->ch[0]);
if(u->id!=0&&u->id!=n+1)printf("%d ",u->id);
if(u->ch[1])dfs(u->ch[1]);
}
int main()
{
//freopen("hoho.txt","r",stdin);
while(scanf("%d%d",&n,&q)!=EOF&&!(n<0&&q<0))
{
cnt=0;
root=NULL;
for(int i=0;i<=n+1;i++)insert(i);
for(int i=1;i<=q;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(a==1)continue;
cut(1,a-1,b);
}
dfs(root);
printf("\n");
}
return 0;
}
E
无脑拍了个倍增的SA T了,度了一个DC3改改就过了。
#include<cstdio>
#include<algorithm>
#include<queue>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
#define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
const int MAXN = 20000000+100;//n*10
int sa[MAXN];
int Rank[MAXN];
int height[MAXN];
int n;
int s[MAXN];
int wa[MAXN],wb[MAXN],wv[MAXN];
int wws[MAXN];
void sort(int *r,int *a,int *b,int n,int m)
{
int i;
for(i=0;i<n;i++) wv[i]=r[a[i]];
for(i=0;i<m;i++) wws[i]=0;
for(i=0;i<n;i++) wws[wv[i]]++;
for(i=1;i<m;i++) wws[i]+=wws[i-1];
for(i=n-1;i>=0;i--) b[--wws[wv[i]]]=a[i];
return;
}
int c0(int *r,int a,int b)
{return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2];}
int c12(int k,int *r,int a,int b)
{if(k==2) return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1);
else return r[a]<r[b]||r[a]==r[b]&&wv[a+1]<wv[b+1];}
void dc3(int *r,int *sa,int n,int m)
{
int i,j,*rn=r+n,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p;
r[n]=r[n+1]=0;
for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i;
sort(r+2,wa,wb,tbc,m);
sort(r+1,wb,wa,tbc,m);
sort(r,wa,wb,tbc,m);
for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++)
rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++;
if(p<tbc) dc3(rn,san,tbc,p);
else for(i=0;i<tbc;i++) san[rn[i]]=i;
for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3;
if(n%3==1) wb[ta++]=n-1;
sort(r,wb,wa,ta,m);
for(i=0;i<tbc;i++) wv[wb[i]=G(san[i])]=i;
for(i=0,j=0,p=0;i<ta && j<tbc;p++)
sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++];
for(;i<ta;p++) sa[p]=wa[i++];
for(;j<tbc;p++) sa[p]=wb[j++];
return;
}
void calheight(int *r, int *sa, int n)
{
int i, j, k = 0;
for (i = 1; i <= n; ++i) Rank[sa[i]] = i;
for (i = 0; i < n; height[Rank[i++]] = k)
for (k ? k-- : 0, j = sa[Rank[i] - 1]; r[i + k] == r[j + k]; ++k);
return;
}
char str[1000003];
bool vis[1000003];
vector<int>vs[1000003];
int tot=0;
int main()
{
/*n=8;
s[8]=0;
s[0]=s[1]=2;
s[2]=s[3]=s[4]=s[5]=1;
s[6]=s[7]=3;
dc3(s,sa,n+1,40);
calheight(s,sa,n);
for(int i=0;i<=n;i++){
printf("%d ", sa[i]);
}
printf("\n");
for(int i=1;i<=n;i++){
printf("%d ", height[i]);
}
printf("\n");*/
scanf("%s",&str);
n=strlen(str);
for(int i=0;i<n;i++){
s[i]=s[i+n]=str[i]-'a'+1;
}
s[2*n]=0;
dc3(s,sa,2*n+1,40);
calheight(s,sa,2*n);
for(int i=0;i<n;i++){
if(!vis[i]){
++tot;
vs[tot].push_back(i);
int p=Rank[i];
while(height[p]>=n){
p--;
if(sa[p]<n){
vis[sa[p]]=true;
vs[tot].push_back(sa[p]);
}
}
p=Rank[i];
while(p<2*n&&height[p+1]>=n){
p++;
if(sa[p]<n){
vis[sa[p]]=true;
vs[tot].push_back(sa[p]);
}
}
sort(vs[tot].begin(),vs[tot].end());
}
}
printf("%d\n",tot);
for(int i=1;i<=tot;i++){
int siz=vs[i].size();
printf("%d ",siz);
for(int j=0;j<siz;j++){
printf("%d%c",vs[i][j],j==siz-1?'\n':' ');
}
}
}
F
这个SOD似乎是一般操作,学习了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=100003;
struct node{
ll cnt[16];
void init(){
memset(cnt,0,sizeof(cnt));
}
};
char s[maxn];
node rec[maxn<<2];
node a;
ll pw[16];
int n,q;
int getnum(char c){
if(c>='0'&&c<='9')return c-'0';
return c-'A'+10;
}
void Union(node& x,node a,node b){
for(int i=0;i<16;i++){
x.cnt[i]=(a.cnt[i]+b.cnt[i])%mod;
}
for(int i=0;i<16;i++){
for(int j=0;j<16;j++){
int k=(i+j)%15;
if(k==0&&(i!=0||j!=0))k=15;
x.cnt[k]=(x.cnt[k]+a.cnt[i]*b.cnt[j])%mod;
}
}
}
void pushup(int u){
Union(rec[u],rec[u+u],rec[u+u+1]);
}
void build(int u,int l,int r){
if(l==r){
rec[u].init();
rec[u].cnt[getnum(s[l])]=1;
return;
}
int mid=(l+r)>>1;
build(u+u,l,mid);
build(u+u+1,mid+1,r);
pushup(u);
}
void update(int u,int l,int r,int p,int x){
if(p<l||p>r)return;
if(l==r){
rec[u].init();
rec[u].cnt[x]=1;
return;
}
int mid=(l+r)>>1;
update(u+u,l,mid,p,x);
update(u+u+1,mid+1,r,p,x);
pushup(u);
}
void query(int u,int l,int r,int ql,int qr,node& a){
if(qr<l||ql>r)return;
if(ql<=l&&r<=qr){
node c;
Union(c,a,rec[u]);
a=c;
return;
}
int mid=(l+r)>>1;
query(u+u,l,mid,ql,qr,a);
query(u+u+1,mid+1,r,ql,qr,a);
}
int main(){
pw[0]=1;
for(int i=1;i<16;i++)pw[i]=pw[i-1]*1021%mod;
scanf("%d%d",&n,&q);
scanf("%s",s+1);
build(1,1,n);
for(int i=1;i<=q;i++){
int typ;
scanf("%d",&typ);
if(typ==1){
int p;
char c[3];
scanf("%d%s",&p,c);
int x=getnum(c[0]);
update(1,1,n,p,x);
}
else {
int l,r;
scanf("%d%d",&l,&r);
a.init();
query(1,1,n,l,r,a);
ll ans=0;
for(int i=0;i<16;i++)ans=(ans+a.cnt[i]*pw[i])%mod;
printf("%lld\n",ans);
}
}
}
G
居然是个bfs。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
vector<int>g[5003];
bool vis[5003];
int n,k,d;
int dfs(int u,int fa,int dis,int d){
int ret=(dis<d);
for(int i=0;i<g[u].size();i++){
int v=g[u][i];
if(vis[v]&&v!=fa){
ret+=dfs(v,u,dis+1,d);
}
}
return ret;
}
ll calc(int d){
ll ret=1;
memset(vis,0,sizeof(vis));
queue<int>q;
q.push(1);
while(!q.empty()){
int u=q.front();
//cout<<u<<endl;
q.pop();
vis[u]=true;
int x=dfs(u,0,0,d)-1;
if(x>=k)return 0;
//cout<<u<<' '<<k-x<<endl;
ret=ret*(k-x)%mod;
for(int i=0;i<g[u].size();i++){
int v=g[u][i];
if(!vis[v])q.push(v);
}
}
return ret;
}
int main(){
scanf("%d%d%d",&n,&k,&d);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
//cout<<calc(d)<<endl;
ll ans=(calc(d)-calc(d+1)+mod)%mod;
printf("%lld\n",ans);
}
H
签到。
#include <bits/stdc++.h>
using namespace std;
bool IsPrime[10000001];
int pre[10000001];
int Pri[2000001],PriN;
void FindPrime ( int MaxN ) {
memset(IsPrime,true,sizeof(IsPrime));
for( int i = 2 ; i <= MaxN ; ++i ){
pre[i]=pre[i-1]+(IsPrime[i]);
if( IsPrime[ i ] )
Pri[ PriN++ ]=i; //将这句话放在下面的循环前以保证PriN和Pri值的完整性
for(int j=0;j<PriN;++j){
if( i*Pri[ j ] > MaxN )
break; //当过大了就跳出
IsPrime[ i * Pri[ j ] ] = 0;
//筛去素数
if( i % Pri[ j ] == 0 ) break;
//这里是关键,如果i是一个合数(这当然是允许的)而且i mod prime[j] = 0
//那么跳出,因为i*prime[ (- over -)j ]一定已经被筛去了,被一个素因子比i小的数
}
}
}
int main(){
FindPrime(10000000);
int n;
scanf("%d",&n);
long long ans=0;
for(int i=1;i<=n;i++){
ans+=1ll*pre[n/i]*(pre[n/i]-1);
}
printf("%lld\n",ans);
}
I
读了论文,发现矩形和三角形很类似。就失了智一样的在矩形里随机了,然后就没有然后了。其实有结论
En=2Hn−1
E
n
=
2
H
n
−
1
,但证明是一坨积分,就没看了。
#include <bits/stdc++.h>
using namespace std;
double a[11]={0,0,0,
3.000000,
3.666486,
4.166492,
4.566907,
4.899598,
5.185593,
5.435899,
5.658031
};
int main(){
int x,y;
int n;
for(int i=1;i<=3;i++)cin>>x>>y;
cin>>n;
//assert(n!=4);
printf("%.10f\n",a[n]);
}
J
板子+1系列。
/*
hdu5130
圆与多边形面积交模板
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <stack>
#include <map>
#include <vector>
#include <queue>
#define eps 1e-8
using namespace std;
struct Point{
double x,y;
Point(double x=0,double y=0):x(x),y(y) {}
void input(){ scanf("%lf%lf",&x,&y); }
};
typedef Point Vector;
struct Circle{
Point c;
double r;
Circle(){}
Circle(Point c,double r):c(c),r(r) {}
};
int dcmp(double x) {
if(x < -eps) return -1;
if(x > eps) return 1;
return 0;
}
template <class T> T sqr(T x) { return x * x;}
Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
bool operator >= (const Point& a, const Point& b) { return a.x >= b.x && a.y >= b.y; }
bool operator <= (const Point& a, const Point& b) { return a.x <= b.x && a.y <= b.y; }
bool operator == (const Point& a, const Point& b) {
return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; }
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
double TriAngleCircleInsection(Circle C, Point A, Point B)
{
Vector OA = A-C.c, OB = B-C.c;
Vector BA = A-B, BC = C.c-B;
Vector AB = B-A, AC = C.c-A;
double DOA = Length(OA), DOB = Length(OB),DAB = Length(AB), r = C.r;
if(dcmp(Cross(OA,OB)) == 0) return 0;
if(dcmp(DOA-C.r) < 0 && dcmp(DOB-C.r) < 0) return Cross(OA,OB)*0.5;
else if(DOB < r && DOA >= r) {
double x = (Dot(BA,BC) + sqrt(r*r*DAB*DAB-Cross(BA,BC)*Cross(BA,BC)))/DAB;
double TS = Cross(OA,OB)*0.5;
return asin(TS*(1-x/DAB)*2/r/DOA)*r*r*0.5+TS*x/DAB;
}
else if(DOB >= r && DOA < r) {
double y = (Dot(AB,AC)+sqrt(r*r*DAB*DAB-Cross(AB,AC)*Cross(AB,AC)))/DAB;
double TS = Cross(OA,OB)*0.5;
return asin(TS*(1-y/DAB)*2/r/DOB)*r*r*0.5+TS*y/DAB;
}
else if(fabs(Cross(OA,OB)) >= r*DAB || Dot(AB,AC) <= 0 || Dot(BA,BC) <= 0) {
if(Dot(OA,OB) < 0){
if(Cross(OA,OB) < 0) return (-acos(-1.0)-asin(Cross(OA,OB)/DOA/DOB))*r*r*0.5;
else return ( acos(-1.0)-asin(Cross(OA,OB)/DOA/DOB))*r*r*0.5;
}
else return asin(Cross(OA,OB)/DOA/DOB)*r*r*0.5;
}
else {
double x = (Dot(BA,BC)+sqrt(r*r*DAB*DAB-Cross(BA,BC)*Cross(BA,BC)))/DAB;
double y = (Dot(AB,AC)+sqrt(r*r*DAB*DAB-Cross(AB,AC)*Cross(AB,AC)))/DAB;
double TS = Cross(OA,OB)*0.5;
return
(asin(TS*(1-x/DAB)*2/r/DOA)+asin(TS*(1-y/DAB)*2/r/DOB))*r*r*0.5 + TS*((x+y)/DAB-1);
}
}
Point p[666],A;
int main()
{
int n,q,i;
scanf("%d",&n);
for(i=1;i<=n;i++) p[i].input();
p[n+1] = p[1];
scanf("%d",&q);
while(q--){
Point A;
A.input();
Circle C=Circle(A,10000);
double sum = 0.0;
for(i=1;i<=n;i++)
sum += TriAngleCircleInsection(C, p[i], p[i+1]);
if(sum<=0){
reverse(p+1,p+1+n);
p[n+1] = p[1];
sum = 0.0;
for(i=1;i<=n;i++)
sum += TriAngleCircleInsection(C, p[i], p[i+1]);
}
int P,Q;
scanf("%d%d",&P,&Q);
sum*=(Q-P);
sum/=Q;
double l=0,r=10000;
for(int j=0;j<150;j++){
double mid=(l+r)/2;
C.r=mid;
double tmp = 0.0;
for(i=1;i<=n;i++)
tmp += TriAngleCircleInsection(C, p[i], p[i+1]);
if(tmp>sum)r=mid;
else l=mid;
}
printf("%.10f\n",l);
}
return 0;
}