只要遇到 bitset,我就一定不会,哈哈哈。
这里最多有m种不同的bitset,每种i的bitset存的是j-i的合法1否则0,然后进行m次&算法就行。不可能每次都要biset都要 (0,n-1) 那些是1,那些是0,不然就是 O(n * m),对于m的某一个 bi ,我只需要把 >=bi 的置为1,比bi小的,只需要在当前基础,把剩余的 >=bi-1 剩余位置置为1就行,就优化为n+m的时间复杂度了,总体题解 O( n ∗ m w \frac{n*m}{w} wn∗m ) ,这个w我也不清楚怎么来的,我感觉 O(n * m) ,n可能很小,这里是bitset的位运算。
题目链接
//#pragma GCC optimize(2)
//#pragma GCC target ("sse4")
#include
//typedef long long ll;
#define ull unsigned long long
#define int long long
#define F first
#define S second
#define endl "\n"//<
#define eps 1e-6
#define base 131
#define lowbit(x) (x&(-x))
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define MAXN 0x7fffffff
#define INF 0x3f3f3f3f3f3f3f3f
#define ferma(a,b) pow(a,b-2)
#define mod(x) (x%mod+mod)%mod
#define pb push_back
#define decimal(x) cout << fixed << setprecision(x);
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
template<typename T> inline T fetch(){T ret;cin >> ret;return ret;}
template<typename T> inline vector<T> fetch_vec(int sz){vector<T> ret(sz);for(auto& it: ret)cin >> it;return ret;}
template<typename T> inline void makeUnique(vector<T>& v){sort(v.begin(), v.end());v.erase(unique(v.begin(), v.end()), v.end());}
void file()
{
#ifdef ONLINE_JUDGE
#else
freopen("D:/LSNU/codeforces/duipai/data.txt","r",stdin);
// freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout);
#endif
}
const int N=4e4+5;
bitset<N>ans,cur;
signed main()
{
IOS;
file();
int n,m;
cin>>n>>m;
vector<pair<int,int> >a(n),b(m);
for(int i=0;i<n;i++)
cin>>a[i].F,a[i].S=i;
for(int i=0;i<m;i++)
cin>>b[i].F,b[i].S=i;
sort(rall(a));
sort(rall(b));
ans.set();
for(int i=0,j=0;i<m;i++)
{
while(j<n&&a[j].F>=b[i].F)
cur.set(a[j++].S);
ans&=cur>>b[i].S;
}
cout<<ans.count()<<endl;
return 0;
}
队友写的,后来补也不会,哈哈哈,真菜。
求Ai,首先想到的是n * m * log n,然后标程给的nm,自己想不到。然后求所有子矩阵的max值,主要这个题的k的是一定的,区间最值,单调队列优化,横向的最值,再跑纵向区间最值,都是nm,STL容器,常数太大TLE,因为自己写的n * m * logn,这次自己终于遇到了,哈哈哈。老实本分的去数组模拟队列。
题目链接
//#pragma GCC optimize(2)
//#pragma GCC target ("sse4")
#include
typedef long long ll;
#define ull unsigned long long
//#define int long long
#define F first
#define S second
#define endl "\n"//<
#define eps 1e-6
#define base 131
#define lowbit(x) (x&(-x))
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define MAXN 0x7fffffff
#define INF 0x3f3f3f3f3f3f3f3f
#define ferma(a,b) pow(a,b-2)
#define mod(x) (x%mod+mod)%mod
#define pb push_back
#define decimal(x) cout << fixed << setprecision(x);
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
template<typename T> inline T fetch()
{
T ret;
cin >> ret;
return ret;
}
template<typename T> inline vector<T> fetch_vec(int sz)
{
vector<T> ret(sz);
for(auto& it: ret)
cin >> it;
return ret;
}
template<typename T> inline void makeUnique(vector<T>& v)
{
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
}
void file()
{
#ifdef ONLINE_JUDGE
#else
freopen("D:/LSNU/codeforces/duipai/data.txt","r",stdin);
// freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout);
#endif
}
const int N=5e3+5;
int a[N][N],maxn[N][N],que[N];
signed main()
{
IOS;
file();
int n,m,k;
cin>>n>>m>>k;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
if(!a[i][j])
for(int k=1; k*i<=n&&k*j<=m; k++)
a[k*i][k*j]=i*j*k;
}
}
for(int i=1; i<=n; i++)
{
int head=1,tail=0;
for(int j=1; j<=m; j++)
{
while(head<=tail&&a[i][que[tail]]<=a[i][j])
tail--;
que[++tail]=j;
while(head<=tail&&que[head]<=j-k)
head++;
maxn[i][j]=a[i][que[head]];
}
}
ll ans=0;
for(int i=k; i<=m; i++)
{
int head=1,tail=0;
for(int j=1; j<=n; j++)
{
while(head<=tail&&maxn[que[tail]][i]<=maxn[j][i])
tail--;
que[++tail]=j;
while(head<=tail&&que[head]<=j-k)
head++;
if(j>=k)
ans+=maxn[que[head]][i];
}
}
cout<<ans<<endl;
return 0;
}
hash+next数组的运用,next确实没想到,还是自己对next不太熟练,哈哈哈,真菜。
或者AC自动机更快,一个学了但不会用的算法。
题目链接
//#pragma GCC optimize(2)
//#pragma GCC target ("sse4")
#include
//typedef long long ll;
#define ull unsigned long long
#define int long long
#define F first
#define S second
#define endl "\n"//<
#define eps 1e-6
#define base 131
#define lowbit(x) (x&(-x))
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define MAXN 0x7fffffff
#define INF 0x3f3f3f3f3f3f3f3f
#define ferma(a,b) pow(a,b-2)
#define mod(x) (x%mod+mod)%mod
#define pb push_back
#define decimal(x) cout << fixed << setprecision(x);
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
template<typename T> inline T fetch(){T ret;cin >> ret;return ret;}
template<typename T> inline vector<T> fetch_vec(int sz){vector<T> ret(sz);for(auto& it: ret)cin >> it;return ret;}
template<typename T> inline void makeUnique(vector<T>& v){sort(v.begin(), v.end());v.erase(unique(v.begin(), v.end()), v.end());}
void file()
{
#ifdef ONLINE_JUDGE
#else
freopen("D:/LSNU/codeforces/duipai/data.txt","r",stdin);
// freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout);
#endif
}
const int mod=998244353;
struct Hash///base131 or 13331
{
vector<ull>pre,suf,p;
Hash(string str)
{
int n=str.size();
pre.resize(n+2);
suf.resize(n+2);
p.resize(n+2);
p[0]=1;
for(int i=1,j=n;i<=n;i++,j--)
{
pre[i]=pre[i-1]*base+str[i-1]-'a'+1;
suf[j]=suf[j+1]*base+str[j-1]-'a'+1;
p[i]=p[i-1]*base;
}
}
ull hash_pre(int l,int r)
{
return pre[r]-pre[l-1]*p[r-l+1];
}
ull hash_suf(int l,int r)
{
return suf[l]-suf[r+1]*p[r-l+1];
}
};
signed main()
{
IOS;
file();
map<ull,int>ma;
int n;
cin>>n;
vector<string>vec(n);
for(auto &it:vec)
{
cin>>it;
Hash te(it);
int len=it.size();
for(int i=1;i<=len;i++)
{
ma[te.hash_pre(i,len)]++;
}
}
int ans=0;
for(auto it:vec)
{
Hash te(it);
int len=it.size();
vector<int>Next,cnt(len+1);
int k=-1,j=0;
Next.pb(-1);
while(j<len)
{
if(k==-1||it[k]==it[j])
{
k++,j++;
Next.pb(k);
}
else
k=Next[k];
}
for(int i=1;i<=len;i++)
{
cnt[i]=ma[te.hash_pre(1ll,i)];
cnt[Next[i]]-=cnt[i];
}
for(int i=1;i<=len;i++)
ans=(ans+cnt[i]*i%mod*i%mod)%mod;
}
cout<<ans<<endl;
return 0;
}
由于给了原点,三点确定一个圆心,固定两点,枚举剩下的点,就可以知道圆上最大数量。
n^2logn,TLE半天,map不能放在两层for算,logn有点大,我的代码,不能映射pair
题目链接
//#pragma GCC optimize(2)
//#pragma GCC target ("sse4")
#include
//typedef long long ll;
#define ull unsigned long long
//#define int long long
#define F first
#define S second
#define endl "\n"//<
#define base 131
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f
#define MAXN 0x7fffffff
#define INF 0x3f3f3f3f3f3f3f3f
#define ferma(a,b) pow(a,b-2)
#define mod(x) (x%mod+mod)%mod
#define pb push_back
#define decimal(x) cout << fixed << setprecision(x);
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
template<typename T> inline T fetch(){T ret;cin >> ret;return ret;}
template<typename T> inline vector<T> fetch_vec(int sz){vector<T> ret(sz);for(auto& it: ret)cin >> it;return ret;}
template<typename T> inline void makeUnique(vector<T>& v){sort(v.begin(), v.end());v.erase(unique(v.begin(), v.end()), v.end());}
void file()
{
#ifdef ONLINE_JUDGE
#else
freopen("D:/LSNU/codeforces/duipai/data.txt","r",stdin);
// freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout);
#endif
}
const double eps = 1e-7;
const double pi = acos(-1.0);
int dcmp(double x)
{
if (fabs(x) < eps)
return 0;
return (x < 0 ? -1 : 1);
}
inline double sqr(double x)
{
return x * x;
}
//*************点
struct Point
{
double x, y;
Point(double _x = 0, double _y = 0) : x(_x), y(_y) {}
void input()
{
cin>>x>>y;
}
void output()
{
printf("%.2f %.2f\n", x, y);
}
bool operator==(const Point &b) const
{
return (dcmp(x - b.x) == 0 && dcmp(y - b.y) == 0);
}
bool operator<(const Point &b) const
{
return (dcmp(x - b.x) == 0 ? dcmp(y - b.y) < 0 : x < b.x);
}
Point operator+(const Point &b) const
{
return Point(x + b.x, y + b.y);
}
Point operator-(const Point &b) const
{
return Point(x - b.x, y - b.y);
}
Point operator*(double a)
{
return Point(x * a, y * a);
}
Point operator/(double a)
{
return Point(x / a, y / a);
}
double len2() //返回长度的平方
{
return sqr(x) + sqr(y);
}
double len() //返回长度
{
return sqrt(len2());
}
Point change_len(double r) //转化为长度为r的向量
{
double l = len();
if (dcmp(l) == 0)
return *this; //零向量返回自身
r /= l;
return Point(x * r, y * r);
}
Point rotate_left() //顺时针旋转90度
{
return Point(-y, x);
}
Point rotate_right() //逆时针旋转90度
{
return Point(y, -x);
}
Point rotate(Point p, double ang) //绕点p逆时针旋转ang
{
Point v = (*this) - p;
double c = cos(ang), s = sin(ang);
return Point(p.x + v.x * c - v.y * s, p.y + v.x * s + v.y * c);
}
Point normal() //单位法向量
{
double l = len();
return Point(-y / l, x / l);
}
};
double cross(Point a, Point b) //叉积
{
return a.x * b.y - a.y * b.x;
}
double dot(Point a, Point b) //点积
{
return a.x * b.x + a.y * b.y;
}
double dis(Point a, Point b) //两个点的距离
{
Point p = b - a;
return p.len();
}
double degree_rad(double ang) //角度转化为弧度
{
return ang / 180 * pi;
}
double rad_degree(double rad) //弧度转化为角度
{
return rad / pi * 180;
}
double rad(Point a, Point b) //两个向量的Ĺ角
{
return fabs(atan2(fabs(cross(a, b)), dot(a, b)));
}
bool parallel(Point a, Point b) //向量平行
{
double p = rad(a, b);
return dcmp(p) == 0 || dcmp(p - pi) == 0;
}
Point Circum(Point a,Point b,Point c){ //已知圆上三点求圆心
double x1=a.x,y1=a.y;
double x2=b.x,y2=b.y;
double x3=c.x,y3=c.y;
double a1=2*(x2-x1);
double b1=2*(y2-y1);
double c1=x2*x2+y2*y2-x1*x1-y1*y1;
double a2=2*(x3-x2);
double b2=2*(y3-y2);
double c2=x3*x3+y3*y3-x2*x2-y2*y2;
double x=(c1*b2-c2*b1)/(a1*b2-a2*b1);
double y=(a1*c2-a2*c1)/(a1*b2-a2*b1);
return Point(x,y);
}
//************直线 线段
struct Line
{
Point s, e; //直线的两个点
double k; //极角 范围[-pi,pi]
Line() {}
Line(Point _s, Point _e)
{
s = _s, e = _e;
k = atan2(e.y - s.y, e.x - s.x);
}
// ax+by+c = 0
Line(double a, double b, double c)
{
if (dcmp(a) == 0)
{
s = Point(0, -c / b);
e = Point(1, -c / b);
}
else if (dcmp(b) == 0)
{
s = Point(-c / a, 0);
e = Point(-c / a, 1);
}
else
{
s = Point(0, -c / b);
e = Point(1, (-c - a) / b);
}
get_angle();
}
//一个点和倾斜角确定直线
Line(Point p, double ang)
{
k = ang;
s = p;
if (dcmp(ang - pi / 2) == 0)
{
e = s + Point(0, 1);
}
else
e = s + Point(1, tan(ang));
}
void input()
{
s.input();
e.input();
}
void output()
{
printf("%.2f,%.2f %.2f,%.2f\n", s.x, s.y, e.x, e.y);
}
void adjust()
{
if (e < s)
swap(e, s);
}
double length() //求线段长度
{
return dis(s, e);
}
void get_angle()
{
k = atan2(e.y - s.y, e.x - s.x);
}
double angle() //直线的倾斜角
{
if (dcmp(k) < 0)
k += pi;
if (dcmp(k - pi) == 0)
k -= pi;
return k;
}
Point operator&(const Line &b) const //直线的交点(保证存在)
{
Point res = s;
double t = (cross(s - b.s, b.s - b.e)) / cross(s - e, b.s - b.e);
res.x += (e.x - s.x) * t;
res.y += (e.y - s.y) * t;
return res;
}
};
int relation(Point p, Line l) //点和直线的关系
{
// 1:在左侧 2:在右侧 3:在直线上
int c = dcmp(cross(p - l.s, l.e - l.s));
if (c < 0)
return 1;
else if (c > 0)
return 2;
else
return 3;
}
bool point_on_halfline(Point p, Line l) //判断点在射线上
{
int id = relation(p, l);
if (id != 3)
return 0;
return dcmp(dot(p - l.s, l.e - l.s)) >= 0;
}
bool point_on_seg(Point p, Line l) //判断点在线段上
{
return dcmp(cross(p - l.s, l.e - l.s)) == 0 &&
dcmp(dot(p - l.s, p - l.e)) <= 0;
//如果忽略端点交点改成小于号就好了
}
bool parallel(Line a, Line b) //直线平行
{
return parallel(a.e - a.s, b.e - b.s);
}
int seg_cross_seg(Line a, Line v) //线段相交判断
{
// 2:规范相交 1:不规范相交 0:不相交
int d1 = dcmp(cross(a.e - a.s, v.s - a.s));
int d2 = dcmp(cross(a.e - a.s, v.e - a.s));
int d3 = dcmp(cross(v.e - v.s, a.s - v.s));
int d4 = dcmp(cross(v.e - v.s, a.e - v.s));
if ((d1 ^ d2) == -2 && (d3 ^ d4) == -2)
return 2;
return (d1 == 0 && dcmp(dot(v.s - a.s, v.s - a.e)) <= 0) ||
(d2 == 0 && dcmp(dot(v.e - a.s, v.e - a.e)) <= 0) ||
(d3 == 0 && dcmp(dot(a.s - v.s, a.s - v.e)) <= 0) ||
(d4 == 0 && dcmp(dot(a.e - v.s, a.e - v.e)) <= 0);
}
int line_cross_seg(Line a, Line v) //直线和线段相交判断 a直线v线段
{
// 2:规范相交 1:非规范相交 0:不相交
int d1 = dcmp(cross(a.e - a.s, v.s - a.s));
int d2 = dcmp(cross(a.e - a.s, v.e - a.s));
if ((d1 ^ d2) == -2)
return 2;
return (d1 == 0 || d2 == 0);
}
int line_cross_line(Line a, Line v) //直线相交判断
{
// 0:平行 1:重合 2:相交
if (parallel(a, v))
return relation(a.e, v) == 3;
return 2;
}
Point line_intersection(Line a, Line v) //直线交点
{
//调用前确保有交点
double a1 = cross(v.e - v.s, a.s - v.s);
double a2 = cross(v.e - v.s, a.e - v.s);
return Point((a.s.x * a2 - a.e.x * a1) / (a2 - a1),
(a.s.y * a2 - a.e.y * a1) / (a2 - a1));
}
int seg_intersectiong(Line a, Line b, Point &p) //求线段交点
{
// 0:没有交点 1:规范相交 2:非规范相交
//调用前确包只有一个交点
int rel = seg_cross_seg(a, b);
if (rel == 0)
return 0;
int cnt = 0;
if (rel == 1)
{
if (point_on_seg(a.e, b))
p = a.e, cnt++;
if (point_on_seg(a.s, b))
p = a.s, cnt++;
if (point_on_seg(b.e, a))
p = b.e, cnt++;
if (point_on_seg(b.s, a))
p = b.s, cnt++;
return 2;
}
p = line_intersection(a, b);
return 1;
}
double point_to_line(Point p, Line a) //点到直线的距离
{
return fabs(cross(p - a.s, a.e - a.s) / a.length());
}
double point_to_seg(Point p, Line a) //点到线段的距离
{
if (dcmp(dot(p - a.s, a.e - a.s)) < 0 || dcmp(dot(p - a.e, a.s - a.e)) < 0)
return min(dis(p, a.e), dis(p, a.s));
return point_to_line(p, a);
}
Point projection(Point p, Line a) //点在直线上的投影
{
return a.s + (((a.e - a.s) * dot(a.e - a.s, p - a.s)) / (a.e - a.s).len2());
}
Point symmetry(Point p, Line a) //点关于直线的对称点
{
Point q = projection(p, a);
return Point(2 * q.x - p.x, 2 * q.y - p.y);
}
signed main()
{
// IOS;
file();
int n;
scanf("%d",&n);
vector<pair<int,int> >vec(n);
for(auto &it:vec)
scanf("%d%d",&it.F,&it.S);
int ans=1,maxn=0;
for(int i=0;i<n;i++)
{
unordered_map<double,int>ma;
for(int j=i+1;j<n;j++)
{
Point a(vec[i].F,vec[i].S),b(vec[j].F,vec[j].S),c(0,0);
Line A(a,c),B(b,c);
if(parallel(A,B))
continue;
Point po=Circum(a,b,c);
double sum=po.x*100000+po.y*100000*35;
ans=max(ans,++ma[sum]+1);
}
}
printf("%d\n",ans);
return 0;
}