今天开始将要转一下做题的OJ了。。
虽然感觉放着权限号在那里不好。。。。。
然后先写一下BC #77的题解吧
1001
就是在枚举子集的过程中我们发现当n > 1时,x出现了偶数次,所以其对答案的贡献就是0;当 n = 1时,其对答案的贡献是 x
1002
简单的排列组合
1003
考虑离线之后我们就可以用并查集做了
1004
DP 是可以用单调队列优化成
O(n)
的 不过我打的是
O(n2)
的
1005
这一题可以考虑离线
离线做法很经典 先将询问按R排序 然后就可以在树状数组上修改了
在线的话代码量可能比较大 就是用可持久话线段树 具体思想和那个询问[l,r]区间的边形成几个联通块差不多
总的来说这一场还是比较水的
PS:感谢这一场带我飞的Manchery大爷
1001
#include<cstdio>
#include<cstdlib>
using namespace std;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
#define ll long long
inline void read(ll &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
ll n,a,ans;
int main()
{
ll Q;
read(Q);
while (Q--)
{
read(n);
for (ll i=1;i<=n;i++)
read(a);
if (n>1)
ans=0;
else
ans=a;
printf("%I64d\n",ans);
}
return 0;
}
1002
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
const int maxn = 1005;
const int mod = 1e9 + 7;
int n;
int cnt[30];
char s[maxn];
int c[maxn][maxn];
int main()
{
int T;
scanf("%d", &T);
c[1][0] = c[1][1] = 1;
for(int i = 2; i <= 1000; i++)
{
c[i][0] = 1;
for(int j = 1; j <= i; j++)
(c[i][j] = c[i - 1][j - 1] + c[i - 1][j]) %= mod;
}
while(T--)
{
scanf("%s", s + 1);
n = strlen(s + 1);
memset(cnt, 0, sizeof(cnt));
for(int i = 1; i <= n; i++) cnt[s[i] - 'a' + 1]++;
int odd = 0;
for(int i = 1; i <= 26; i++) odd += cnt[i] & 1;
if(odd > 1) puts("0");
else
{
int tot = 0;
long long ans = 1;
for(int i = 1; i <= 26; i++)
{
cnt[i] /= 2;
if(cnt[i])
{
(ans *= c[cnt[i] + tot][cnt[i]]) %= mod;
tot += cnt[i];
}
}
cout << ans << std;
}
}
return 0;
}
1003
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
#define ll long long
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
inline int read(char *s)
{
char c=nc(); int len=0;
for (;!(c>='0' && c<='1');c=nc());
for (;c>='0' && c<='1';s[++len]=c,c=nc()); s[++len]=0; return len-1;
}
int n,m,S,T,K;
int fat[250005];
char M[505][505];
int X[250005],Y[250005];
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
inline int P(int x,int y){
if (x==0) return S;
if (x==n+1) return T;
return (x-1)*m+y;
}
inline int getfat(int u){
return u==fat[u]?u:fat[u]=getfat(fat[u]);
}
inline void link(int x,int y){
int fx=getfat(x),fy=getfat(y);
if (fx!=fy)
fat[fx]=fy;
}
inline bool Jud(int x,int y){
int fx=getfat(x),fy=getfat(y);
return fx==fy;
}
int main()
{
int Q;
read(Q);
while (Q--)
{
read(n); read(m); S=n*m+1; T=n*m+2;
for (int i=1;i<=n;i++)
read(M[i]);
read(K);
for (int i=1;i<=K;i++) read(X[i]),read(Y[i]),X[i]++,Y[i]++,M[X[i]][Y[i]]='1';
for (int i=1;i<=T;i++) fat[i]=i;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (M[i][j]!='1')
{
int a,b;
for (int k=0;k<4;k++)
{
a=i+dx[k],b=j+dy[k];
if (b>0 && b<=m)
if (a==0 || a==n+1 || M[a][b]!='1')
link(P(a,b),P(i,j));
}
}
if (Jud(S,T)){
printf("-1\n");
continue;
}
int flag=0;
for (int i=K;i && !flag;i--)
{
int a,b;
for (int k=0;k<4;k++)
{
a=X[i]+dx[k],b=Y[i]+dy[k];
if (b>0 && b<=m)
if (a==0 || a==n+1 || M[a][b]!='1')
link(P(a,b),P(X[i],Y[i]));
}
M[X[i]][Y[i]]='0';
if (Jud(S,T)){
printf("%d\n",i);
flag=1;
}
}
if (!flag)
printf("0\n");
}
return 0;
}
1004
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
#define ll long long
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
int n,m;
int sum[2005];
double f[2005];
inline double Log(int x){
return log((double)x)/log(2.0);
}
int main()
{
int Q,a;
read(Q);
while (Q--)
{
cl(sum); cl(f);
read(m); read(n);
for (int i=1;i<=n;i++) read(a),sum[++a]=1;
for (int i=1;i<=m;i++) sum[i]+=sum[i-1];
for (int i=1;i<=m;i++)
for (int j=i-1;j>=0;j--)
{
if (sum[i]-sum[j]>1) break;
if (sum[i]-sum[j]<1) continue;
f[i]=max(f[i],f[j]+Log(i-j));
}
printf("%I64d\n",(ll)(f[m]*1000000.0));
}
return 0;
}
1005
在线打法
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
struct Rec
{
int a,b,c;
inline friend bool operator !=(Rec a,Rec b)
{return (a.a^b.a)|(a.b^b.b)|(a.c^b.c);}
};
const
int MaxHash=213133;
inline int Calc(Rec Key)
{
return ((Key.a*3+Key.b*76721+Key.c*23)%MaxHash+MaxHash)%MaxHash;
}
struct Hash
{
Rec Key;
int Latest;
Hash*next;
}*Table[MaxHash];
Hash Hash_Cache[MaxHash];
int Hash_Tot;
inline Hash*New_Hash(){return Hash_Cache+Hash_Tot++;}
Hash *Ans;
bool find(Rec Key,Hash*Cur)
{
if(!Cur)return false;
if(Cur->Key!=Key)return find(Key,Cur->next);
Ans=Cur;return true;
}
inline void insert(Rec Key,int place,int time)
{
Hash*tp=New_Hash();
tp->next=Table[place];
Table[place]=tp;
tp->Latest=time;
tp->Key=Key;
}
struct Seg
{
Seg *lc,*rc;
int l,r;
int data;
}*Root[200001];
Seg Seg_Cache[5000000];
int Seg_Tot;
inline Seg*New_Seg()
{return Seg_Cache+Seg_Tot++;}
int Query(Seg*Cur,int L)
{
if(!Cur)return 0;
if(Cur->r<L)return 0;
else if(Cur->l>=L)return Cur->data;
else
{
int res=0;
res=Query(Cur->lc,L);
res+=Query(Cur->rc,L);
return res;
}
}
Seg*Modify(Seg*Cur,int L)
{
Seg*Ne=New_Seg();
*Ne=*Cur;
Ne->data++;
if(Cur->l^Cur->r)
{
int Mid=Cur->l+Cur->r>>1;
if(Mid<L)
Ne->rc=Modify(Ne->rc,L);
else
Ne->lc=Modify(Ne->lc,L);
}
return Ne;
}
Seg*Build(int L,int R)
{
Seg*Ne=New_Seg();
Ne->l=L;Ne->r=R;
Ne->lc=Ne->rc=NULL;
Ne->data=0;
if(L^R)
{
int Mid=L+R>>1;
Ne->rc=Build(Mid+1,R);
Ne->lc=Build(L,Mid);
}
return Ne;
}
int n,Q;
int A[200001];
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
int Val[200001];
int main()
{
Rec tp;
int pl,T;
read(T);
while(T--)
{
Hash_Tot=Seg_Tot=0;
memset(Table,0,sizeof(Table));
read(n);
Root[1]=Root[0]=Root[2]=Build(1,n);
for(int i=1;i<=n;i++)
read(A[i]);
for(int i=3;i<=n;i++)
{
tp.a=A[i-2],tp.b=A[i-1],tp.c=A[i];
Val[i]=0;
if(tp.a<=tp.b&&tp.b<=tp.c)
if(!find(tp,Table[pl=Calc(tp)]))
insert(tp,pl,i),Root[i]=Modify(Root[i-1],1);
else
{
Root[i]=Modify(Root[i-1],Ans->Latest);
Ans->Latest=i;
}
else Val[i]=-1,Root[i]=Root[i-1];
Val[i]=Val[i-1]+Val[i]+1;
}
read(Q);
int L,R;
while(Q--)
{
read(L),read(R);
if(R-L<=1)
{puts("0");continue;}
int ans=Query(Root[R],L+2);
ans=Val[R]-Val[L+1]-ans;
printf("%d\n",ans);
}
}
getchar();
getchar();
getchar();
getchar();
getchar();
getchar();
getchar();
getchar();
return 0;
}