2020牛客多校第二场

G题总结

只要遇到 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} wnm ,这个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;
}

F题总结

队友写的,后来补也不会,哈哈哈,真菜。
求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;
}

A题总结

hash+next数组的运用,next确实没想到,还是自己对next不太熟练,哈哈哈,真菜。
或者AC自动机更快,一个学了但不会用的算法。
2020牛客多校第二场_第1张图片
题目链接

//#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;
}

B题总结

由于给了原点,三点确定一个圆心,固定两点,枚举剩下的点,就可以知道圆上最大数量。
n^2logn,TLE半天,map不能放在两层for算,logn有点大,我的代码,不能映射pair或者point,常数太大,要么首先一个结点还得重载小于符号或者哈希point.或者无序map。
题目链接

//#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;
}

你可能感兴趣的:(比赛)