A:随便怎么暴力。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 25
char getc(){char c=getchar();while (c!='.'&&c!='#') c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
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<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int T,n,m;
char a[N][N];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
T=read();
while (T--)
{
n=read(),m=read();
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
a[i][j]=getc();
int u=0,v=0;
for (int i=1;i<=n;i++)
{
int cnt=0;
for (int j=1;j<=m;j++)
if (a[i][j]=='.') cnt++;
if (cnt>v) u=i,v=cnt;
}
int l=0,r=0;
for (int j=1;j<=m;j++)
if (a[u][j]=='.') {l=j;break;}
for (int j=m;j>=1;j--)
if (a[u][j]=='.') {r=j;break;}
cout<<(r-l)/2<<' '<<u<<' '<<(l+r)/2<<endl;
}
return 0;
//NOTICE LONG LONG!!!!!
}

  B:显然选择单字符子串能形成n种不同的串。容易发现其他方案一定是由进位产生的,考虑固定某个9为子串右端点会产生多少种方案。数一下由其往前有多少个连续的9,这一段的每个后缀都会产生一种方案。然后再往前看一个数,若不为0答案再+1;若为0,由于所选串不能有前置0,需要找一下之前有没有非零数,若有则答案+1。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while (c!='.'&&c!='#') c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
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<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
char s[N];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
int T=read();
while (T--)
{
scanf("%s",s+1);int n=strlen(s+1);
ll ans=0;
bool flag=0;int cnt=0;
int first=n+1;for (int i=1;i<=n;i++) if (s[i]!='0') {first=i;break;}
char last='0';
for (int i=1;i<=n;i++)
{
if (s[i]!='9')
{
cnt=0,ans++;
last=s[i];
}
else
{
cnt++;
ans+=cnt;
if (last=='0') ans+=i-cnt>first;
else ans++;
}
}
cout<<ans<<endl;
}
return 0;
//NOTICE LONG LONG!!!!!
}

  C:状态尽量最小表示一下,哈希暴力记搜。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define N 200010
char getc(){char c=getchar();while (c!='.'&&c!='#') c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
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<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int T,n;
struct data
{
int x,y;
bool operator <(const data&a) const
{
return x>a.x||x==a.x&&y>a.y;
}
bool operator ==(const data&a) const
{
return x==a.x&&y==a.y;
}
}a[22];
map<ull,int> f;
ull calc(data *a)
{
ull s=0;
for (int i=0;i<=16;i++)
s=s*13+a[i].x,s=s*17+a[i].y;
return s;
}
int work(data *a)
{
ull h=calc(a);
if (f.find(h)!=f.end()) return f[h];
bool flag=0;
for (int i=1;i<=16;i++)
if (a[i].x==0) break;
else
{
if (i==a[0].x) continue;
data b[22];
for (int j=0;j<=16;j++) b[j]=a[j];
a[i].x--;data c=a[i];swap(c.x,c.y);for (int j=1;j<=16;j++) swap(a[j].x,a[j].y);sort(a+1,a+17);
for (int j=1;j<=16;j++) if (a[j]==c) {a[0].x=j;break;}
int u=work(a);
for (int j=0;j<=16;j++) a[j]=b[j];
if (u==-1) return f[h]=1;
if (u==0) flag=1;
}
if (flag) return f[h]=0;
else return f[h]=-1;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
#endif
T=read();a[0].x=1;f[calc(a)]=0;
while (T--)
{
n=read();
for (int i=1;i<=20;i++) a[i].x=a[i].y=0;
for (int i=1;i<=n;i++) a[read()].x++;
for (int i=1;i<=n;i++) a[read()].y++;
a[0].x=0;
sort(a+1,a+21);
int x=work(a);
if (x==1) puts("AA wins");
if (x==-1) puts("dreamoon wins");
if (x==0) puts("Draw");
}
return 0;
//NOTICE LONG LONG!!!!!
}

  D:大讨论大约是可以做的,但大约不是给人写的。考虑简单的做法。套路的将坐标系转45°,使菱形变为正方形,处理出二维前缀和。枚举正方形中心,二分半径,根据该正方形是否包含了所有没有草的点调整二分半径方向。然后判断该正方形中是否没有草,若是则更新答案。于是O(nmlog(n+m))。也可以做到线性,大概没啥本质区别。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 1010
#define mp(x,y) make_pair((x),(y))
char getc(){char c=getchar();while (c!='#'&&c!='.') c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
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<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
typedef pair<int,int> pii;
int T,n,m,a[N<<1][N<<1],s[N<<1][N<<1],s2[N<<1][N<<1];
pii trans(pii a){return mp(a.first+a.second,a.first-a.second+m);}
int calc(int x1,int y1,int x2,int y2)
{
x1=max(x1,1),y1=max(y1,1);x2=min(x2,n+m),y2=min(y2,n+m);
return s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1];
}
int calc2(int x1,int y1,int x2,int y2)
{
x1=max(x1,1),y1=max(y1,1);x2=min(x2,n+m),y2=min(y2,n+m);
return s2[x2][y2]-s2[x1-1][y2]-s2[x2][y1-1]+s2[x1-1][y1-1];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
T=read();
while (T--)
{
n=read(),m=read();
int cnt=0;
for (int i=1;i<=n+m;i++)
for (int j=1;j<=n+m;j++)
s[i][j]=s2[i][j]=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
char c=getc();
if (c=='#') a[i][j]=0;
else a[i][j]=1;
cnt+=a[i][j];
s[i+j][i-j+m]=a[i][j];s2[i+j][i-j+m]=1-a[i][j];
}
for (int i=1;i<=n+m;i++)
for (int j=1;j<=n+m;j++)
s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1],
s2[i][j]+=s2[i-1][j]+s2[i][j-1]-s2[i-1][j-1];
int ansx=0,ansy=0,ansr=n+m+1;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
int l=0,r=max(n,m),ans=n+m+1;
pii t=trans(mp(i,j));
while (l<=r)
{
int mid=l+r>>1;
if (calc(t.first-mid,t.second-mid,t.first+mid,t.second+mid)==cnt) ans=mid,r=mid-1;
else l=mid+1;
}
if (ans!=n+m+1&&calc(t.first-ans,t.second-ans,t.first+ans,t.second+ans)==cnt&&calc2(t.first-ans,t.second-ans,t.first+ans,t.second+ans)==0)
if (ans<ansr||ans==ansr&&i<ansx||ans==ansr&&i==ansx&&j<ansy) ansx=i,ansy=j,ansr=ans;
}
if (ansr==n+m+1) printf("-1 -1 -1\n");
else printf("%d %d %d\n",ansr,ansx,ansy);
}
return 0;
}

  E:对于牛的极长连续段,显然这些牛只能吃与其相邻的草,所以每一段牛互不相干可以分开考虑。对于一段牛,可能吃到的草的数量是牛的数量+1,找到这段里没被吃的草,以该位置将这段牛分成两半,然后只要保证两边的牛都不吃到该草即可。不妨设第一个位置是没被吃的草,容易发现不合法仅当某头向左走的牛移动时,其前方所有牛都已经吃过草。计算概率即可。注意虽然实际上其前方所有向右走的牛都已经吃过草就已经不合法了,但我们只应考虑该牛直接导致不合法的概率。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define P 998244353
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
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<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int T,n,inv[N];
char s[N];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
#endif
T=read();
inv[0]=inv[1]=1;for (int i=2;i<=100001;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;
while (T--)
{
n=2*read()+1;int ans=1;
scanf("%s",s+1);
int cnt1=0,cnt2=0;
for (int i=1;i<=n;i++)
{
if ((i&1)&&(s[i]=='.')) cnt1++;
if (!(i&1)&&(s[i]=='L'||s[i]=='R')) ans=1ll*ans*(++cnt2)%P;
}
if (cnt1!=cnt2) ans=0;
else
for (int i=2;i<=n;i+=2)
if (s[i]=='L'||s[i]=='R')
{
int t=i;
while (t+2<=n&&s[t+2]!='.') t+=2;
int cnt=0,pos=0;
for (int j=i-1;j<=t+1;j+=2)
if (s[j]=='.') cnt++;else pos=j;
if (cnt!=(t-i>>1)+1) {ans=0;break;}
cnt=0;
for (int j=pos-1;j>=i;j-=2)
{
if (s[j]!='L') ans=1ll*ans*cnt%P*inv[cnt+1]%P;
cnt++;
}
cnt=0;
for (int j=pos+1;j<=t;j+=2)
{
if (s[j]!='R') ans=1ll*ans*cnt%P*inv[cnt+1]%P;
cnt++;
}
i=t;
}
printf("%d\n",ans);
}
return 0;
//NOTICE LONG LONG!!!!!
}

  F:首先注意到合法欧拉序的任意子串都可以作为某合法欧拉序的前缀。所以随着左端点移动,可以作为欧拉序前缀的右端点单调不降。two pointers扫过去,过程中计算所有与左端点相同的点的贡献即可。

  判断一个序列是否是欧拉序显然用栈扫一遍即可。考虑将左端点移动一位的影响,可以发现对于树来说,是将根的第一个儿子提为根而将原来的根变为其最后一个儿子。于是维护的话把栈改为双端队列即可。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 1000010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
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<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int T,n,a[N],cnt[N],p[N];
ll s[N];
deque<int> q;
signed main()
{
#ifndef ONLINE_JUDGE
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
#endif
T=read();
while (T--)
{
n=read();ll ans=0;
for (int i=1;i<=n;i++) a[i]=read(),p[i]=n+1;
s[n+1]=cnt[n+1]=0;
for (int i=1;i<=n;i++)
{
s[i]=s[p[a[i]]]+i;
cnt[i]=cnt[p[a[i]]]+1;
p[a[i]]=i;
}
for (int i=1;i<=n;i++) p[i]=0;q.clear();
int r=0;
for (int i=1;i<=n;i++)
{
if (i>1)
{
q.pop_front();
if (p[a[i-1]]>=i)
{
if (!q.empty()&&q.front()==a[i]) q.pop_front();
q.push_front(a[i-1]);
q.push_front(a[i]);
}
}
while (r<n)
{
if (p[a[r+1]]<i) q.push_back(a[++r]);
else
{
int x=q.back();q.pop_back();
if (q.empty()||q.back()!=a[r+1]) {q.push_back(x);break;}
++r;
}
p[a[r]]=r;
}
ans+=s[p[a[i]]]-s[i]-1ll*(i-1)*(cnt[p[a[i]]]-cnt[i])+1;
}
cout<<ans<<endl;
}
return 0;
//NOTICE LONG LONG!!!!!
}

  似乎有小裙子耶

最新文章

  1. 剑指offer三: 斐波拉契数列
  2. Hanio汉诺塔代码递归实现
  3. LINQ构建交叉表
  4. Raspberry Pi3 ~ 配置网络
  5. &lt;&lt;c 和指针 &gt;&gt; 部分笔记。
  6. 【BZOJ 1046】 1046: [HAOI2007]上升序列
  7. 神器 Sublime Text 3 的一些常用快捷键
  8. Sky数 2097
  9. 判断括号字符串是否为合法+求n对括号的所有组合
  10. PHP Memcached 实现简单数据库缓存
  11. 前端自动化测试漫长路之——Selenium初探
  12. Mecanim之IK动画
  13. 网络协议与OSI体系结构
  14. java第七周动手动脑
  15. Linux 小知识翻译 - 目录 (完结)
  16. you have mixed tabs and spaces fix this
  17. Keepalived系列一:Keepalived.conf 详解
  18. dp之多维背包hdu4501
  19. PhoneGap 获得APP的VersionName
  20. 树莓派驱动DHT22

热门文章

  1. asp.net三层架构增删改查
  2. ___Html页面使用Ajax做数据显示
  3. WPF 禁用TextBox的触摸后自动弹出虚拟键盘
  4. Java开发笔记(八十三)利用注解技术检查空指针
  5. Docker+SpringBoot远程发布
  6. webpack中使用DefinePlugin定义全局变量
  7. cesium 之三维漫游飞行效果实现篇(附源码下载)
  8. OrmLite-更符合面向对象的数据库操作方式
  9. Eclipse导出包含第三方Jar的工程
  10. 深入理解Git的实现原理