<commit_before>#include "GameBoardLayer.h"
#include "GameManager.h"
#include "CMO_tile.h"
#include "CMO_dot.h"
#include "CMO_line.h"
#include "CMO_item.h"

USING_NS_CC;

bool CGameBoardLayer::init()
{
	//////////////////////////////
	// 1. super init first
	if ( !CCLayer::init() )
	{
		return false;
	}

	//////////////////////////////
	// 2. add resources
	m_VisibleSize = CCDirector::sharedDirector()->getVisibleSize();

	int rowNum = 0;
	int columnNum = 0;

	switch (CGameManager::GetInstance()->GetSelectedMapSize() )
	{
	case MS_5X5:
		rowNum = 5;
		columnNum = 5;
		break;
	case MS_7X7:
		rowNum = 7;
		columnNum = 7;
		break;
	case MS_8X8:
		rowNum = 8;
		columnNum = 8;
		break;
	default:
		break;
	}

	m_Board = CCSprite::create(
		PLAYSCENE_BOARD.c_str(),
		CCRect(0, 0, columnNum * DEFAULT_TILE_WIDTH, rowNum * DEFAULT_TILE_HEIGHT)
		);
	m_Board->setAnchorPoint(ccp(0.5f, 0.5f));
	m_Board->setPosition(ccp(m_VisibleSize.width / 2, m_VisibleSize.height / 2) );
	this->addChild(m_Board);

	m_BoardOrigin.x = m_VisibleSize.width/2 - (float(columnNum)/2 * DEFAULT_TILE_WIDTH);
	m_BoardOrigin.y = m_VisibleSize.height/2;

	float m_OriginX = 0.0f;
	float m_OriginY = m_Board->getContentSize().height/2;

	float m_LineOriginX = m_OriginX;
	float m_LineOriginY = m_OriginY;

	float m_DeltaX = DEFAULT_TILE_WIDTH/2;
	float m_DeltaY = DEFAULT_TILE_HEIGHT/2;

	for (int i = 1; i < rowNum * 2 + 2; ++i)
	{
		for (int j = 1; j < columnNum * 2 + 2; ++j)
		{
			IndexedPosition pos;
			pos.m_PosI = i;
			pos.m_PosJ = j;

			//«‡, ø≠ ∏µŒ ¬¶ºˆ ¿œ ∞ÊøÏ ≈∏¿œ¿ª ±◊∏∞¥Ÿ.
			if ( i % 2 == 0 && j % 2 == 0)
			{
				CMO_tile* pTile = CMO_tile::create();
				pTile->setImage(pos);
				pTile->setPosition(ccp(m_OriginX+m_DeltaX*(j/2-1),m_OriginY+m_DeltaY*(j/2-1)));

				m_Board->addChild(pTile, 0);

                //add item
                if (CGameManager::GetInstance()->GetItem(IndexedPosition(i,j))!= ITEM_NOTHING)
                {
                    CMO_item* pItem = CMO_item::create();
                    pItem->setImage(IndexedPosition(i,j));
                    pItem->setPosition( ccp(m_OriginX+m_DeltaX*(j/2-1),m_OriginY+m_DeltaY*(j/2-1)) );
                    m_Board->addChild(pItem, 4);
                }

			}
			// «‡, ø≠ ∏µŒ »¶ºˆ¿œ ∞ÊøÏ ¥Â¿ª ±◊∏∞¥Ÿ.
			else if ( i % 2 == 1 && j % 2 == 1)
			{
				CMO_dot* pDot = CMO_dot::Create();
				pDot->setPosition( ccp( m_OriginX+m_DeltaX*(j/2),m_OriginY+m_DeltaY*(j/2) ) );

				m_Board->addChild(pDot, 2);
			}

			//±◊ ø‹ø°¥¬ º±¿Ã¥Ÿ.(i¬¶ºˆ/j»¶ºˆ ∂«¥¬ i»¶ºˆ/j¬¶ºˆ)
			else
			{
				CMO_line* pLine = CMO_line::create();
				pLine->setImage(pos);

				if (j%2 == 0)
					pLine->setPosition( ccp( m_LineOriginX+m_DeltaX*(j/2-1),m_LineOriginY+m_DeltaY*(j/2-1) ) );
				else
					pLine->setPosition( ccp( m_LineOriginX+m_DeltaX*(j/2),m_LineOriginY+m_DeltaY*(j/2) ) );

				m_Board->addChild(pLine, 1);

			}

		}
		if (i%2==0)
		{
			m_OriginX += m_DeltaX;
			m_OriginY -= m_DeltaY;
		}
		else
		{
			m_LineOriginX += m_DeltaX;
			m_LineOriginY -= m_DeltaY;
		}
		}

	this->setTouchEnabled(true);

    return true;
}

void CGameBoardLayer::DrawMapObjects()
{

}

void CGameBoardLayer::ccTouchesBegan( CCSet* pTouches, CCEvent* pEvent )
{
	CCTouch *pTouch = (CCTouch*)pTouches->anyObject();

	m_StartPoint = pTouch->getLocationInView();
    Highlight(m_StartPoint, 1);
	CCLog("Start point =  %f, %f", m_StartPoint.x,m_StartPoint.y);

}

void CGameBoardLayer::ccTouchesMoved(CCSet* pTouches, cocos2d::CCEvent* pEvent)
{
    CCTouch *pTouch = (CCTouch*)pTouches->anyObject();
    m_middlePoint = pTouch->getLocationInView();
    Highlight(m_middlePoint, 0);
}

void CGameBoardLayer::ccTouchesEnded( CCSet *pTouches, CCEvent *pEvent )
{
	CCTouch *pTouch = (CCTouch*)pTouches->anyObject();

	m_EndPoint  = pTouch->getLocationInView();
	CCLog("End point =  %f, %f", m_EndPoint.x,m_EndPoint.y);
    removeChildByTag(0);
    removeChildByTag(1);
	DrawLine();
}

void CGameBoardLayer::DrawLine()
{
	IndexedPosition startIndex = ConvertCoordinate(m_StartPoint);
	IndexedPosition endIndex = ConvertCoordinate(m_EndPoint);

	if (startIndex.m_PosI == endIndex.m_PosI)
	{
		if (endIndex.m_PosJ - startIndex.m_PosJ == 2)
		{
			CGameManager::GetInstance()->DrawLine( IndexedPosition(startIndex.m_PosI, endIndex.m_PosJ - 1) );
			m_LineDirection = DI_UP;
		}
		else if (startIndex.m_PosJ - endIndex.m_PosJ == 2)
		{
			CGameManager::GetInstance()->DrawLine( IndexedPosition(startIndex.m_PosI, startIndex.m_PosJ - 1) );
			m_LineDirection = DI_DOWN;
		}
	}
	else if (startIndex.m_PosJ == endIndex.m_PosJ)
	{
		if (endIndex.m_PosI - startIndex.m_PosI == 2)
		{
			CGameManager::GetInstance()->DrawLine( IndexedPosition(endIndex.m_PosI - 1, startIndex.m_PosJ) );
			m_LineDirection = DI_DOWN;
		}
		else if (startIndex.m_PosI - endIndex.m_PosI == 2)
		{
			CGameManager::GetInstance()->DrawLine( IndexedPosition(startIndex.m_PosI - 1, startIndex.m_PosJ) );
			m_LineDirection = DI_UP;
		}
	}
}

IndexedPosition CGameBoardLayer::ConvertCoordinate(CCPoint point)
{
	//새로운 변환 함수 작성
	//각 행마다 기울기는 y = (DeltaY/DeltaX) x 로 동일하지만, y절편이 -deltaY/2만큼씩 감소한다.
	//따라서 마우스 좌표값으로 해당 행을 구한 뒤, x값을 계산하여 열을 구해낼 수 있다.

	// (0,0)을 씬의 왼쪽 아래로 옮겨온다.
	point.y = m_VisibleSize.height - point.y - m_BoardOrigin.y;
	point.x -= m_BoardOrigin.x;

	//이제 인덱스로 바꾼다.
	IndexedPosition indexedPosition;

	//먼저, 범위를 벗어났는지 확인한다.
	if ( point.x > m_Board->getContentSize().width + TOUCH_AREA ||
		point.x< - TOUCH_AREA||
		point.y > m_Board->getContentSize().height/2 + TOUCH_AREA ||
		point.y < -m_Board->getContentSize().height/2- TOUCH_AREA)
	{
		indexedPosition.m_PosI = 0;
		indexedPosition.m_PosJ = 0;
		return indexedPosition;
	}

	float deltaX = DEFAULT_TILE_WIDTH/2;
	float deltaY = DEFAULT_TILE_HEIGHT/2;
	float interceptY = 0.0f;

	float remainderX = static_cast<int>(point.x) % static_cast<int>(deltaX);
	float remainderY = static_cast<int>(point.y) % static_cast<int>(deltaY) ;

	//일단 이 아이를 다듬어야 해.

	if ( remainderX < TOUCH_AREA)
	{
		point.x -= remainderX;
	}
	else if (remainderX > deltaX - TOUCH_AREA)
	{
		point.x +=(deltaX - remainderX);
	}

	if ( abs(remainderY) < TOUCH_AREA)
	{
		if (remainderY>=0)
			point.y -= remainderY;
		else
			point.y += remainderY;
	}
	else if (abs(remainderY) > deltaY - TOUCH_AREA)
	{
		if (remainderY>=0)
			point.y +=(deltaY - remainderY);
		else
			point.y -=(deltaY + remainderY);
	}

	//y절편을 계산한다.
	interceptY = point.y - (deltaY/deltaX)*point.x;

	//행을 계산한다.
	indexedPosition.m_PosI = static_cast<int>(interceptY/-DEFAULT_TILE_HEIGHT);

	//열을 계산한다.
	indexedPosition.m_PosJ = static_cast<int>(point.x - deltaX*indexedPosition.m_PosI)/deltaX;

	//점에 해당하도록 계산한다.
	indexedPosition.m_PosI = indexedPosition.m_PosI*2+1;
	indexedPosition.m_PosJ = indexedPosition.m_PosJ*2+1;

	CCLog("CONVERTED : %d, %d",indexedPosition.m_PosI, indexedPosition.m_PosJ);

	return indexedPosition;
}

void CGameBoardLayer::Highlight(cocos2d::CCPoint point,int isClicked)
{
    if(getChildByTag(0)!=nullptr)
    {
        removeChildByTag(0);
    }

    //Dot에 해당하는지 검사.
    //마우스 오버시 무조건 highlight, 클릭된 것은 클릭이 끝날 때 까지 highlight 유지.

    IndexedPosition indexedPosition = ConvertCoordinate(point);
    point.y = m_VisibleSize.height - point.y - m_BoardOrigin.y;
	point.x -= m_BoardOrigin.x;

    //범위를 벗어날 경우. 그냥 종료.
	if ( point.x > m_Board->getContentSize().width + TOUCH_AREA ||
		point.x< - TOUCH_AREA||
		point.y > m_Board->getContentSize().height/2 + TOUCH_AREA ||
		point.y < -m_Board->getContentSize().height/2- TOUCH_AREA)
	{
		return;
	}

    float deltaX = DEFAULT_TILE_WIDTH/2;
	float deltaY = DEFAULT_TILE_HEIGHT/2;

    //2. converted IndexPosition이 Dot에 해당하는지 검사.
    if(indexedPosition.m_PosI%2==1 && indexedPosition.m_PosJ%2 ==1)
    {
        //고쳐라.
        if(isClicked == 0 && (abs(indexedPosition.m_PosI-ConvertCoordinate(m_StartPoint).m_PosI)+abs(indexedPosition.m_PosJ-ConvertCoordinate(m_StartPoint).m_PosJ))>2 )
        {
            return;
        }

        CCPoint tempP;
        //시작점
        tempP.x = m_BoardOrigin.x + (indexedPosition.m_PosI/2) * deltaX;
        tempP.y = m_BoardOrigin.y - (indexedPosition.m_PosI/2) * deltaY;

        tempP.x += deltaX * (indexedPosition.m_PosJ/2) ;
        tempP.y += deltaY * (indexedPosition.m_PosJ/2) ;

        CCSprite* pHighlight = CCSprite::create("image/playscene_dot_highlight.png");

        pHighlight->setPosition(tempP);
        pHighlight->setTag(isClicked);
        addChild(pHighlight,3);

        //line
        if (isClicked!=3)
        {
            removeChildByTag(3);
            CCSprite * lineHighlight = CCSprite::create();
            float wide = sqrtf(powf(m_middlePoint.x-tempP.x, 2)+powf(m_middlePoint.y-tempP.y,2));
            lineHighlight->setTextureRect(CCRectMake(0, 0, wide, 100));
            lineHighlight->setColor(ccc3(192,41,20));
            lineHighlight->setPosition(ccp(500,500));
            lineHighlight->setTag(3);
            addChild(lineHighlight,5);
        }
    }
    return;

}

void CGameBoardLayer::update(float dt)
{
	//ø©±‚º≠ childµÈ¿ª æ˜µ•¿Ã∆Æ «ÿæﬂ «’¥œ¥Ÿ.
	//CCLog("1111 Board layer updated");
	CCArray* mapObjects = m_Board->getChildren();

	unsigned int objectNum = mapObjects->count();
	for (unsigned int i = 0; i < objectNum; ++i)
	{
		mapObjects->objectAtIndex(i)->update(dt);
	}

}<commit_msg>불완전한 라인 터치감 진행중 !! 수정해야해<commit_after>#include "GameBoardLayer.h"
#include "GameManager.h"
#include "CMO_tile.h"
#include "CMO_dot.h"
#include "CMO_line.h"
#include "CMO_item.h"

USING_NS_CC;

bool CGameBoardLayer::init()
{
	//////////////////////////////
	// 1. super init first
	if ( !CCLayer::init() )
	{
		return false;
	}

	//////////////////////////////
	// 2. add resources
	m_VisibleSize = CCDirector::sharedDirector()->getVisibleSize();

	int rowNum = 0;
	int columnNum = 0;

	switch (CGameManager::GetInstance()->GetSelectedMapSize() )
	{
	case MS_5X5:
		rowNum = 5;
		columnNum = 5;
		break;
	case MS_7X7:
		rowNum = 7;
		columnNum = 7;
		break;
	case MS_8X8:
		rowNum = 8;
		columnNum = 8;
		break;
	default:
		break;
	}

	m_Board = CCSprite::create(
		PLAYSCENE_BOARD.c_str(),
		CCRect(0, 0, columnNum * DEFAULT_TILE_WIDTH, rowNum * DEFAULT_TILE_HEIGHT)
		);
	m_Board->setAnchorPoint(ccp(0.5f, 0.5f));
	m_Board->setPosition(ccp(m_VisibleSize.width / 2, m_VisibleSize.height / 2) );
	this->addChild(m_Board);

	m_BoardOrigin.x = m_VisibleSize.width/2 - (float(columnNum)/2 * DEFAULT_TILE_WIDTH);
	m_BoardOrigin.y = m_VisibleSize.height/2;

	float m_OriginX = 0.0f;
	float m_OriginY = m_Board->getContentSize().height/2;

	float m_LineOriginX = m_OriginX;
	float m_LineOriginY = m_OriginY;

	float m_DeltaX = DEFAULT_TILE_WIDTH/2;
	float m_DeltaY = DEFAULT_TILE_HEIGHT/2;

	for (int i = 1; i < rowNum * 2 + 2; ++i)
	{
		for (int j = 1; j < columnNum * 2 + 2; ++j)
		{
			IndexedPosition pos;
			pos.m_PosI = i;
			pos.m_PosJ = j;

			//«‡, ø≠ ∏µŒ ¬¶ºˆ ¿œ ∞ÊøÏ ≈∏¿œ¿ª ±◊∏∞¥Ÿ.
			if ( i % 2 == 0 && j % 2 == 0)
			{
				CMO_tile* pTile = CMO_tile::create();
				pTile->setImage(pos);
				pTile->setPosition(ccp(m_OriginX+m_DeltaX*(j/2-1),m_OriginY+m_DeltaY*(j/2-1)));

				m_Board->addChild(pTile, 0);

                //add item
                if (CGameManager::GetInstance()->GetItem(IndexedPosition(i,j))!= ITEM_NOTHING)
                {
                    CMO_item* pItem = CMO_item::create();
                    pItem->setImage(IndexedPosition(i,j));
                    pItem->setPosition( ccp(m_OriginX+m_DeltaX*(j/2-1),m_OriginY+m_DeltaY*(j/2-1)) );
                    m_Board->addChild(pItem, 5);
                }

			}
			// «‡, ø≠ ∏µŒ »¶ºˆ¿œ ∞ÊøÏ ¥Â¿ª ±◊∏∞¥Ÿ.
			else if ( i % 2 == 1 && j % 2 == 1)
			{
				CMO_dot* pDot = CMO_dot::Create();
				pDot->setPosition( ccp( m_OriginX+m_DeltaX*(j/2),m_OriginY+m_DeltaY*(j/2) ) );

				m_Board->addChild(pDot, 2);
			}

			//±◊ ø‹ø°¥¬ º±¿Ã¥Ÿ.(i¬¶ºˆ/j»¶ºˆ ∂«¥¬ i»¶ºˆ/j¬¶ºˆ)
			else
			{
				CMO_line* pLine = CMO_line::create();
				pLine->setImage(pos);

				if (j%2 == 0)
					pLine->setPosition( ccp( m_LineOriginX+m_DeltaX*(j/2-1),m_LineOriginY+m_DeltaY*(j/2-1) ) );
				else
					pLine->setPosition( ccp( m_LineOriginX+m_DeltaX*(j/2),m_LineOriginY+m_DeltaY*(j/2) ) );

				m_Board->addChild(pLine, 1);

			}

		}
		if (i%2==0)
		{
			m_OriginX += m_DeltaX;
			m_OriginY -= m_DeltaY;
		}
		else
		{
			m_LineOriginX += m_DeltaX;
			m_LineOriginY -= m_DeltaY;
		}
		}

	this->setTouchEnabled(true);

    return true;
}

void CGameBoardLayer::DrawMapObjects()
{

}

void CGameBoardLayer::ccTouchesBegan( CCSet* pTouches, CCEvent* pEvent )
{
	CCTouch *pTouch = (CCTouch*)pTouches->anyObject();

	m_StartPoint = pTouch->getLocationInView();
    Highlight(m_StartPoint, 1);
	CCLog("Start point =  %f, %f", m_StartPoint.x,m_StartPoint.y);

}

void CGameBoardLayer::ccTouchesMoved(CCSet* pTouches, cocos2d::CCEvent* pEvent)
{
    CCTouch *pTouch = (CCTouch*)pTouches->anyObject();
    m_middlePoint = pTouch->getLocationInView();
    Highlight(m_middlePoint, 0);
}

void CGameBoardLayer::ccTouchesEnded( CCSet *pTouches, CCEvent *pEvent )
{
	CCTouch *pTouch = (CCTouch*)pTouches->anyObject();

	m_EndPoint  = pTouch->getLocationInView();
	CCLog("End point =  %f, %f", m_EndPoint.x,m_EndPoint.y);
    removeChildByTag(0);
    removeChildByTag(1);
	DrawLine();
}

void CGameBoardLayer::DrawLine()
{
	IndexedPosition startIndex = ConvertCoordinate(m_StartPoint);
	IndexedPosition endIndex = ConvertCoordinate(m_EndPoint);

	if (startIndex.m_PosI == endIndex.m_PosI)
	{
		if (endIndex.m_PosJ - startIndex.m_PosJ == 2)
		{
			CGameManager::GetInstance()->DrawLine( IndexedPosition(startIndex.m_PosI, endIndex.m_PosJ - 1) );
			m_LineDirection = DI_UP;
		}
		else if (startIndex.m_PosJ - endIndex.m_PosJ == 2)
		{
			CGameManager::GetInstance()->DrawLine( IndexedPosition(startIndex.m_PosI, startIndex.m_PosJ - 1) );
			m_LineDirection = DI_DOWN;
		}
	}
	else if (startIndex.m_PosJ == endIndex.m_PosJ)
	{
		if (endIndex.m_PosI - startIndex.m_PosI == 2)
		{
			CGameManager::GetInstance()->DrawLine( IndexedPosition(endIndex.m_PosI - 1, startIndex.m_PosJ) );
			m_LineDirection = DI_DOWN;
		}
		else if (startIndex.m_PosI - endIndex.m_PosI == 2)
		{
			CGameManager::GetInstance()->DrawLine( IndexedPosition(startIndex.m_PosI - 1, startIndex.m_PosJ) );
			m_LineDirection = DI_UP;
		}
	}
}

IndexedPosition CGameBoardLayer::ConvertCoordinate(CCPoint point)
{
	//새로운 변환 함수 작성
	//각 행마다 기울기는 y = (DeltaY/DeltaX) x 로 동일하지만, y절편이 -deltaY/2만큼씩 감소한다.
	//따라서 마우스 좌표값으로 해당 행을 구한 뒤, x값을 계산하여 열을 구해낼 수 있다.

	// (0,0)을 씬의 왼쪽 아래로 옮겨온다.
	point.y = m_VisibleSize.height - point.y - m_BoardOrigin.y;
	point.x -= m_BoardOrigin.x;

	//이제 인덱스로 바꾼다.
	IndexedPosition indexedPosition;

	//먼저, 범위를 벗어났는지 확인한다.
	if ( point.x > m_Board->getContentSize().width + TOUCH_AREA ||
		point.x< - TOUCH_AREA||
		point.y > m_Board->getContentSize().height/2 + TOUCH_AREA ||
		point.y < -m_Board->getContentSize().height/2- TOUCH_AREA)
	{
		indexedPosition.m_PosI = 0;
		indexedPosition.m_PosJ = 0;
		return indexedPosition;
	}

	float deltaX = DEFAULT_TILE_WIDTH/2;
	float deltaY = DEFAULT_TILE_HEIGHT/2;
	float interceptY = 0.0f;

	float remainderX = static_cast<int>(point.x) % static_cast<int>(deltaX);
	float remainderY = static_cast<int>(point.y) % static_cast<int>(deltaY) ;

	//일단 이 아이를 다듬어야 해.

	if ( remainderX < TOUCH_AREA)
	{
		point.x -= remainderX;
	}
	else if (remainderX > deltaX - TOUCH_AREA)
	{
		point.x +=(deltaX - remainderX);
	}

	if ( abs(remainderY) < TOUCH_AREA)
	{
		if (remainderY>=0)
			point.y -= remainderY;
		else
			point.y += remainderY;
	}
	else if (abs(remainderY) > deltaY - TOUCH_AREA)
	{
		if (remainderY>=0)
			point.y +=(deltaY - remainderY);
		else
			point.y -=(deltaY + remainderY);
	}

	//y절편을 계산한다.
	interceptY = point.y - (deltaY/deltaX)*point.x;

	//행을 계산한다.
	indexedPosition.m_PosI = static_cast<int>(interceptY/-DEFAULT_TILE_HEIGHT);

	//열을 계산한다.
	indexedPosition.m_PosJ = static_cast<int>(point.x - deltaX*indexedPosition.m_PosI)/deltaX;

	//점에 해당하도록 계산한다.
	indexedPosition.m_PosI = indexedPosition.m_PosI*2+1;
	indexedPosition.m_PosJ = indexedPosition.m_PosJ*2+1;

	CCLog("CONVERTED : %d, %d",indexedPosition.m_PosI, indexedPosition.m_PosJ);

	return indexedPosition;
}

void CGameBoardLayer::Highlight(cocos2d::CCPoint point,int isClicked)
{
    //Dot에 해당하는지 검사.
    //마우스 오버시 무조건 highlight, 클릭된 것은 클릭이 끝날 때 까지 highlight 유지.

    IndexedPosition indexedPosition = ConvertCoordinate(point);
    point.y = m_VisibleSize.height - point.y - m_BoardOrigin.y;
	point.x -= m_BoardOrigin.x;

    //범위를 벗어날 경우. 그냥 종료.
	if ( point.x > m_Board->getContentSize().width + TOUCH_AREA ||
		point.x< - TOUCH_AREA||
		point.y > m_Board->getContentSize().height/2 + TOUCH_AREA ||
		point.y < -m_Board->getContentSize().height/2- TOUCH_AREA)
	{
		return;
	}
    ///

    if(getChildByTag(0)!=nullptr)
    {
        removeChildByTag(0);
    }

    //line
    if(isClicked==0)
    {
        if(getChildByTag(3)!=nullptr)
        {
            //removeChildByTag(3);
        }
        getChildByTag(3)->setScaleX(sqrt(powf(m_middlePoint.x-m_StartPoint.x,2)+powf(m_middlePoint.y-m_StartPoint.y,2)));

        //angle direction
        IndexedPosition startIdx = ConvertCoordinate(m_StartPoint);
        if(indexedPosition.m_PosI-startIdx.m_PosI==2)
        {
            getChildByTag(3)->setRotation(33.0f);
        }
        else if(indexedPosition.m_PosI-startIdx.m_PosI==-2)
        {
            getChildByTag(3)->setRotation(213.0f);
        }
        else if(indexedPosition.m_PosJ-startIdx.m_PosJ==-2)
        {
            getChildByTag(3)->setRotation(147.0f);
        }
        else if(indexedPosition.m_PosJ-startIdx.m_PosJ==2)
        {
            getChildByTag(3)->setRotation(327.0f);
        }

    }

    ///

    float deltaX = DEFAULT_TILE_WIDTH/2;
	float deltaY = DEFAULT_TILE_HEIGHT/2;

    //2. converted IndexPosition이 Dot에 해당하는지 검사.
    if(indexedPosition.m_PosI%2==1 && indexedPosition.m_PosJ%2 ==1)
    {
        //고쳐라.
        if(isClicked == 0 && (abs(indexedPosition.m_PosI-ConvertCoordinate(m_StartPoint).m_PosI)+abs(indexedPosition.m_PosJ-ConvertCoordinate(m_StartPoint).m_PosJ))>2 )
        {
            return;
        }

        CCPoint tempP;
        //시작점
        tempP.x = m_BoardOrigin.x + (indexedPosition.m_PosI/2) * deltaX;
        tempP.y = m_BoardOrigin.y - (indexedPosition.m_PosI/2) * deltaY;

        tempP.x += deltaX * (indexedPosition.m_PosJ/2) ;
        tempP.y += deltaY * (indexedPosition.m_PosJ/2) ;

        CCSprite* pHighlight = CCSprite::create("image/playscene_dot_highlight.png");

        pHighlight->setPosition(tempP);
        pHighlight->setTag(isClicked);
        addChild(pHighlight,4);

        //line
        if (isClicked==1)
        {
            removeChildByTag(3);
            CCSprite * lineHighlight = CCSprite::create();
            lineHighlight->setTextureRect(CCRectMake(0, 0, 1, 25));
            lineHighlight->setColor(ccc3(192,41,20));
            lineHighlight->setPosition(tempP);
            lineHighlight->setAnchorPoint(ccp(0,0.5));
            lineHighlight->setTag(3);
            addChild(lineHighlight,3);
        }

    }
    return;

}

void CGameBoardLayer::update(float dt)
{
	//ø©±‚º≠ childµÈ¿ª æ˜µ•¿Ã∆Æ «ÿæﬂ «’¥œ¥Ÿ.
	//CCLog("1111 Board layer updated");
	CCArray* mapObjects = m_Board->getChildren();

	unsigned int objectNum = mapObjects->count();
	for (unsigned int i = 0; i < objectNum; ++i)
	{
		mapObjects->objectAtIndex(i)->update(dt);
	}

}<|endoftext|>


<commit_before>// $Id$
//
//  Copyright (C) 2014 Greg Landrum and Rational Discovery LLC
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//

#include <GraphMol/RDKitBase.h>
#include <GraphMol/MonomerInfo.h>
#include <GraphMol/RDKitQueries.h>
#include <GraphMol/SmilesParse/SmilesParse.h>
#include <RDGeneral/types.h>
#include <RDGeneral/RDLog.h>
//#include <boost/log/functions.hpp>

#include <iostream>
using namespace std;
using namespace RDKit;

void testBasics()
{
  BOOST_LOG(rdInfoLog)  << "-----------------------\n Basic Allocations" << std::endl;
  Atom *a1 = new Atom(6);
  Bond *b1 = new Bond();
  ROMol *m1 = new ROMol();

  a1 = NULL; // intentional leak
  BOOST_LOG(rdInfoLog)  << "Finished" << std::endl;
}

void testSMILES()
{
  BOOST_LOG(rdInfoLog)  << "-----------------------\n SMILES Read" << std::endl;
  string smi="CCOC";
  ROMol *m = SmilesToMol(smi);
  smi="C1COC1";
  ROMol *m2 = SmilesToMol(smi);

  BOOST_LOG(rdInfoLog)  << "Finished" << std::endl;
}

void testMol()
{
  RWMol *m1 = new RWMol();
  m1->addAtom(new Atom(6),true,true);
  m1->addAtom(new Atom(6),true,true);
  m1->addAtom(new Atom(7),true,true);
  m1->addAtom(new Atom(6),true,true);
  m1->addBond(0,1,Bond::SINGLE);
  m1->addBond(1,2,Bond::SINGLE);
  m1->addBond(2,3,Bond::SINGLE);
  MolOps::sanitizeMol(*m1);
}

// -------------------------------------------------------------------
int main()
{
  RDLog::InitLogs();
  //boost::logging::enable_logs("rdApp.info");
  // test1();  // <- this doesn't seem to actually do anything
#if 1
  //testBasics();
  testSMILES();
  testMol();
#endif

  return 0;
}
<commit_msg>add a larger smiles test<commit_after>// $Id$
//
//  Copyright (C) 2014 Greg Landrum and Rational Discovery LLC
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//

#include <GraphMol/RDKitBase.h>
#include <GraphMol/MonomerInfo.h>
#include <GraphMol/RDKitQueries.h>
#include <GraphMol/SmilesParse/SmilesParse.h>
#include <RDGeneral/types.h>
#include <RDGeneral/RDLog.h>
//#include <boost/log/functions.hpp>

#include <iostream>
using namespace std;
using namespace RDKit;

void testBasics()
{
  BOOST_LOG(rdInfoLog)  << "-----------------------\n Basic Allocations" << std::endl;
  Atom *a1 = new Atom(6);
  Bond *b1 = new Bond();
  ROMol *m1 = new ROMol();

  a1 = NULL; // intentional leak
  BOOST_LOG(rdInfoLog)  << "Finished" << std::endl;
}

void testSMILES()
{
  BOOST_LOG(rdInfoLog)  << "-----------------------\n SMILES Read" << std::endl;
  string smi="CCOC";
  ROMol *m = SmilesToMol(smi);
  smi="C1COC1";
  ROMol *m2 = SmilesToMol(smi);

  BOOST_LOG(rdInfoLog)  << "Finished" << std::endl;
}

void testMol()
{
  RWMol *m1 = new RWMol();
  m1->addAtom(new Atom(6),true,true);
  m1->addAtom(new Atom(6),true,true);
  m1->addAtom(new Atom(7),true,true);
  m1->addAtom(new Atom(6),true,true);
  m1->addBond(0,1,Bond::SINGLE);
  m1->addBond(1,2,Bond::SINGLE);
  m1->addBond(2,3,Bond::SINGLE);
  MolOps::sanitizeMol(*m1);
}

void testMols()
{
  std::string smis[] = {
    "CN1CCC[C@H]1c2cccnc2",
    "CC1(C)[C@@H](N2[C@@H](CC2=O)S1(=O)=O)C(=O)O",
    "C[C@]1(Cn2ccnn2)[C@@H](N3[C@@H](CC3=O)S1(=O)=O)C(=O)O",
    "CCN(CC)C(=O)[C@@H]1CN(C)[C@H]2Cc3c[nH]c4cccc(C2=C1)c34",
    "CCCN(CCC)[C@H]1CCc2c(O)cccc2C1",
    "CC(=O)NC[C@H]1CN(C(=O)O1)c2ccc(cc2)C(=O)C",
    "CC1(C)Oc2ccc3C=CC(=O)Oc3c2[C@@H](OC(=O)C45CCC(C)(C(=O)O4)C5(C)C)[C@H]1OC(=O)C67CCC(C)(C(=O)O6)C7(C)C",
    "CCC(C)(C)C(=O)C(=O)N1CCC[C@H]1C(=O)OCCCc2cccnc2",
    "CN1N=C(S/C/1=N/C(=O)C)S(=O)(=O)N",
    "COc1ccc(cc1)[C@@H]2Sc3ccccc3N(CCN(C)C)C(=O)[C@@H]2OC(=O)C",
    "EOS"
  };
  for(int i=0;smis[i]!="EOS";++i){
    RWMol *m=SmilesToMol(smis[i]);
  }
}

// -------------------------------------------------------------------
int main()
{
  RDLog::InitLogs();
  //boost::logging::enable_logs("rdApp.info");
  // test1();  // <- this doesn't seem to actually do anything
#if 1
  //testBasics();
  //testSMILES();
  //testMol();
  testMols();
#endif

  return 0;
}
<|endoftext|>


<commit_before>/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-7-14 22:46:09
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

const long long MOD = 1000000007;

long long power(long long x, long long n)
{
  if (n == 0)
  {
    return 1;
  }
  else if (n % 2 == 1)
  {
    return (x * power(x, n - 1)) % MOD;
  }
  else
  {
    long long half = power(x, n / 2);
    return (half * half) % MOD;
  }
}

int N;
ll h[1010];
ll DP[2][1010];

int main()
{
  cin >> N;
  h[0] = 0;
  for (auto i = 1; i <= N; i++)
  {
    cin >> h[i];
    cerr << "h[" << i << "] = " << h[i] << endl;
  }
  DP[0][0] = 0;
  DP[0][1] = 1;
  for (auto i = 0; i < N; i++)
  {
    if (h[i] < h[i + 1])
    {
      if (h[i] >= 2)
      {
        ll t = h[i + 1] - h[i];
        ll p = power(2, t);
        DP[i + 1][1] = (((2 * DP[i][1]) % MOD) * p) % MOD;
        DP[i + 1][0] = (DP[i][0] * p) % MOD;
      }
      else if (h[i] == 1)
      {
        ll t = h[i + 1] - 2;
        ll p = power(2, t);
        DP[i + 1][1] = (((2 * DP[i][1]) % MOD) * p) % MOD;
        DP[i + 1][0] = DP[i + 1][1];
      }
      else
      {
        if (h[i + 1] >= 2)
        {
          ll t = h[i + 1] - 2;
          ll p = power(2, t);
          DP[i + 1][1] = (((2 * DP[i][1]) % MOD) * p) % MOD;
          DP[i + 1][0] = DP[i + 1][1];
        }
        else if (h[i + 1] == 1)
        {
          DP[i + 1][1] = (((DP[i][1] + DP[i][0]) % MOD) * 2) % MOD;
          DP[i + 1][0] = 0;
        }
        else
        {
          DP[i + 1][1] = (DP[i][1] + DP[i][0]) % MOD;
          DP[i + 1][0] = 0;
        }
      }
    }
    else if (h[i + 1] >= 2)
    {
      DP[i + 1][1] = (2 * DP[i][1]) % MOD;
      DP[i + 1][0] = DP[i][0];
    }
    else if (h[i + 1] == 1)
    {
      DP[i + 1][1] = (((DP[i][1] + DP[i][0]) % MOD) * 2) % MOD;
      DP[i + 1][0] = 0;
    }
    else
    {
      DP[i + 1][1] = (DP[i][1] + DP[i][0]) % MOD;
      DP[i + 1][0] = 0;
    }
    cerr << "DP[" << i + 1 << "] = " << DP[i + 1][0] << " " << DP[i + 1][1] << endl;
  }
  cout << (DP[N][1] + DP[N][0]) % MOD << endl;
}<commit_msg>tried D.cpp to 'D'<commit_after>/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-7-14 22:46:09
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

const long long MOD = 1000000007;

long long power(long long x, long long n)
{
  if (n == 0)
  {
    return 1;
  }
  else if (n % 2 == 1)
  {
    return (x * power(x, n - 1)) % MOD;
  }
  else
  {
    long long half = power(x, n / 2);
    return (half * half) % MOD;
  }
}

int N;
ll h[1010];
ll DP[2][1010];

int main()
{
  cin >> N;
  h[0] = 0;
  for (auto i = 1; i <= N; i++)
  {
    cin >> h[i];
    // cerr << "h[" << i << "] = " << h[i] << endl;
  }
  DP[0][0] = 0;
  DP[0][1] = 1;
  for (auto i = 0; i < N; i++)
  {
    cerr << "i = " << i << endl;
    if (h[i] < h[i + 1])
    {
      if (h[i] >= 2)
      {
        ll t = h[i + 1] - h[i];
        ll p = power(2, t);
        DP[i + 1][1] = (((2 * DP[i][1]) % MOD) * p) % MOD;
        DP[i + 1][0] = (DP[i][0] * p) % MOD;
      }
      else if (h[i] == 1)
      {
        ll t = h[i + 1] - 2;
        ll p = power(2, t);
        DP[i + 1][1] = (((2 * DP[i][1]) % MOD) * p) % MOD;
        DP[i + 1][0] = DP[i + 1][1];
      }
      else
      {
        if (h[i + 1] >= 2)
        {
          ll t = h[i + 1] - 2;
          ll p = power(2, t);
          DP[i + 1][1] = (((2 * DP[i][1]) % MOD) * p) % MOD;
          DP[i + 1][0] = DP[i + 1][1];
        }
        else if (h[i + 1] == 1)
        {
          DP[i + 1][1] = (((DP[i][1] + DP[i][0]) % MOD) * 2) % MOD;
          DP[i + 1][0] = 0;
        }
        else
        {
          DP[i + 1][1] = (DP[i][1] + DP[i][0]) % MOD;
          DP[i + 1][0] = 0;
        }
      }
    }
    else if (h[i + 1] >= 2)
    {
      DP[i + 1][1] = (2 * DP[i][1]) % MOD;
      DP[i + 1][0] = DP[i][0];
    }
    else if (h[i + 1] == 1)
    {
      DP[i + 1][1] = (((DP[i][1] + DP[i][0]) % MOD) * 2) % MOD;
      DP[i + 1][0] = 0;
    }
    else
    {
      DP[i + 1][1] = (DP[i][1] + DP[i][0]) % MOD;
      DP[i + 1][0] = 0;
    }
    cerr << "DP[" << i + 1 << "] = " << DP[i + 1][0] << " " << DP[i + 1][1] << endl;
  }
  cout << (DP[N][1] + DP[N][0]) % MOD << endl;
}<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 5/16/2020, 9:50:51 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

int main()
{
  ll A{0}, B{0};
  min_heap<ll> R;
  max_heap<ll> L;
  int Q;
  cin >> Q;
  for (auto q = 0; q < Q; ++q)
  {
    int c;
    cin >> c;
    if (c == 1)
    {
      ll a, b;
      cin >> a >> b;
      B += b;
      R.push(a);
      L.push(a);
      auto r{R.top()};
      auto l{L.top()};
      A += abs(r - l);
      if (r < l)
      {
        R.pop();
        L.pop();
        R.push(l);
        L.push(r);
      }
    }
    else
    {
      cout << A + B << endl;
    }
  }
}
<commit_msg>tried F.cpp to 'F'<commit_after>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 5/16/2020, 9:50:51 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

int main()
{
  ll A{0}, B{0};
  min_heap<ll> R;
  max_heap<ll> L;
  int Q;
  cin >> Q;
  for (auto q = 0; q < Q; ++q)
  {
    int c;
    cin >> c;
    if (c == 1)
    {
      ll a, b;
      cin >> a >> b;
      B += b;
      R.push(a);
      L.push(a);
      auto r{R.top()};
      auto l{L.top()};
      A += abs(r - l);
      if (r < l)
      {
        R.pop();
        L.pop();
        R.push(l);
        L.push(r);
      }
    }
    else
    {
      cout << R.top() << " " << A + B << endl;
    }
  }
}
<|endoftext|>


<commit_before>#define DEBUG 1

/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 6/9/2019, 9:09:02 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

/*
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}

void No()
{
  cout << "No" << endl;
  exit(0);
}
*/

/*
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
*/

// const ll MOD = 1000000007;

int H, W;
string S[2010];
bool X[2010][2010];
ll A[2010][2010];
ll B[2010][2010];

ll solve()
{
  for (auto i = 0; i < H; i++)
  {
    ll t = 0;
    for (auto j = 0; j < W; j++)
    {
      if (X[i][j])
      {
        t++;
      }
      else
      {
        for (auto k = j; k > j - t; k--)
        {
          A[i][k] = t;
        }
        t = 0;
      }
    }
    for (auto k = W - 1; k > W - 1 - t; k--)
    {
      A[i][k] = t;
    }
  }
  for (auto j = 0; j < W; j++)
  {
    ll t = 0;
    for (auto i = 0; i < H; i++)
    {
      if (X[i][j])
      {
        t++;
      }
      else
      {
        for (auto k = i; k > i - t; k--)
        {
          B[k][j] = t;
        }
        t = 0;
      }
    }
    for (auto k = H - 1; k > H - 1 - t; k--)
    {
      B[k][j] = t;
    }
  }
  ll ans = 0;
  for (auto i = 0; i < H; i++)
  {
    for (auto j = 0; j < W; j++)
    {
      ans = max(ans, A[i][j] + B[i][j]);
    }
  }
  return ans;
}

int main()
{
  cin >> H >> W;
  for (auto i = 0; i < H; i++)
  {
    cin >> S[i];
  }
  for (auto i = 0; i < H; i++)
  {
    for (auto j = 0; j < W; j++)
    {
      X[i][j] = (S[i][j] == '.');
    }
  }
  cout << solve() - 1 << endl;
}<commit_msg>tried D.cpp to 'D'<commit_after>#define DEBUG 1

/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 6/9/2019, 9:09:02 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

/*
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}

void No()
{
  cout << "No" << endl;
  exit(0);
}
*/

/*
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
*/

// const ll MOD = 1000000007;

int H, W;
string S[2010];
bool X[2010][2010];
ll A[2010][2010];
ll B[2010][2010];

ll solve()
{
  for (auto i = 0; i < H; i++)
  {
    ll t = 0;
    for (auto j = 0; j < W; j++)
    {
      if (X[i][j])
      {
        t++;
      }
      else
      {
        for (auto k = j; k > j - t; k--)
        {
          A[i][k] = t;
        }
        t = 0;
      }
    }
    for (auto k = W - 1; k > W - 1 - t; k--)
    {
      A[i][k] = t;
    }
  }
  for (auto j = 0; j < W; j++)
  {
    ll t = 0;
    for (auto i = 0; i < H; i++)
    {
      if (X[i][j])
      {
        t++;
      }
      else
      {
        for (auto k = i; k > i - t; k--)
        {
          B[k][j] = t;
        }
        t = 0;
      }
    }
    for (auto k = H - 1; k > H - 1 - t; k--)
    {
      B[k][j] = t;
    }
  }
  ll ans = 0;
  for (auto i = 0; i < H; i++)
  {
    for (auto j = 0; j < W; j++)
    {
      ans = max(ans, A[i][j] + B[i][j]);
    }
  }
  return ans;
}

int main()
{
  cin >> H >> W;
  for (auto i = 0; i < H; i++)
  {
    cin >> S[i];
  }
  for (auto i = 0; i < H; i++)
  {
    for (auto j = 0; j < W; j++)
    {
      X[i][j] = (S[i][j] == '.');
    }
  }
  solve();
#if DEBUG == 1
  cerr << "A" << endl;
  for (auto i = 0; i < H; i++)
  {
    for (auto j = 0; j < W; j++)
    {
      cerr << A[i][j];
    }
    cerr << endl;
  }
  cerr << "B" << endl;
  for (auto i = 0; i < H; i++)
  {
    for (auto j = 0; j < W; j++)
    {
      cerr << B[i][j];
    }
    cerr << endl;
  }
#endif
  // cout << solve() - 1 << endl;
}<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 7/7/2019, 9:44:50 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
const int MAX_SIZE = 1000010;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a) { return (*this *= power(MOD - 2)); }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
mint inv[MAX_SIZE];
mint fact[MAX_SIZE];
mint factinv[MAX_SIZE];
void init()
{
  inv[1] = 1;
  for (int i = 2; i < MAX_SIZE; i++)
  {
    inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
  }
  fact[0] = factinv[0] = 1;
  for (int i = 1; i < MAX_SIZE; i++)
  {
    fact[i] = mint(i) * fact[i - 1];
    factinv[i] = inv[i] * factinv[i - 1];
  }
}
mint choose(int n, int k)
{
  if (n >= 0 && k >= 0 && n - k >= 0)
  {
    return fact[n] * factinv[k] * factinv[n - k];
  }
  return 0;
}
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// const double epsilon = 1e-10;
// const ll infty = 1000000000000000LL;
// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

ll N, K;
vector<int> V[100010];
vector<int> children[100010];
bool visited[100010];

void dfs(int n)
{
  if (!visited[n])
  {
    visited[n] = true;
    for (auto x : V[n])
    {
      if (!visited[x])
      {
        children[n].push_back(x);
        dfs(x);
      }
    }
  }
}

int main()
{
  init();
  cin >> N >> K;
  for (auto i = 0; i < N; i++)
  {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    V[a].push_back(b);
    V[b].push_back(a);
  }
  dfs(0);
  queue<int> Q;
  Q.push(0);
  mint ans = 1;
  while (!Q.empty())
  {
    int n = Q.front();
    Q.pop();
    ll child = children[n].size();
    ll D = K - 1;
    if (n != 0)
    {
      D--;
    }
    ans *= choose(D, child);
    for (auto x : children[n])
    {
      Q.push(x);
    }
  }
  cout << ans << endl;
}<commit_msg>tried E.cpp to 'E'<commit_after>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 7/7/2019, 9:44:50 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
const int MAX_SIZE = 1000010;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a) { return (*this *= power(MOD - 2)); }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
mint inv[MAX_SIZE];
mint fact[MAX_SIZE];
mint factinv[MAX_SIZE];
void init()
{
  inv[1] = 1;
  for (int i = 2; i < MAX_SIZE; i++)
  {
    inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
  }
  fact[0] = factinv[0] = 1;
  for (int i = 1; i < MAX_SIZE; i++)
  {
    fact[i] = mint(i) * fact[i - 1];
    factinv[i] = inv[i] * factinv[i - 1];
  }
}
mint choose(int n, int k)
{
  if (n >= 0 && k >= 0 && n - k >= 0)
  {
    return fact[n] * factinv[k] * factinv[n - k];
  }
  return 0;
}
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// const double epsilon = 1e-10;
// const ll infty = 1000000000000000LL;
// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

ll N, K;
vector<int> V[100010];
vector<int> children[100010];
bool visited[100010];

void dfs(int n)
{
  if (!visited[n])
  {
    visited[n] = true;
    for (auto x : V[n])
    {
      if (!visited[x])
      {
        children[n].push_back(x);
        dfs(x);
      }
    }
  }
}

int main()
{
  init();
  cin >> N >> K;
  for (auto i = 0; i < N; i++)
  {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    V[a].push_back(b);
    V[b].push_back(a);
  }
  dfs(0);
  queue<int> Q;
  Q.push(0);
  mint ans = 1;
#if DEBUG == 1
  cerr << "Here" << endl;
#endif
  while (!Q.empty())
  {
    int n = Q.front();
    Q.pop();
    ll child = children[n].size();
    ll D = K - 1;
    if (n != 0)
    {
      D--;
    }
    ans *= choose(D, child);
    for (auto x : children[n])
    {
      Q.push(x);
    }
  }
  cout << ans << endl;
}<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 8/12/2019, 7:02:46 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 3000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

vector<int> count(string const &S)
{
  vector<int> cnt(3, 0);
  for (auto x : S)
  {
    cnt[x - 'A']++;
  }
  return cnt;
}

string reduce(string const &S)
{
  stringstream res{};
  char c{'x'};
  for (auto x : S)
  {
    if (x == c)
    {
      continue;
    }
    else
    {
      res << x;
      c = x;
    }
  }
  return res.str();
}

map<char, char> make_map(string const &S)
{
  vector<int> cnt = count(S);
  vector<tuple<int, char>> V;
  for (auto i = 0; i < 3; i++)
  {
    V.emplace_back(cnt[i], 'A' + i);
  }
  sort(V.begin(), V.end());
  map<char, char> res;
  for (auto i = 0; i < 3; i++)
  {
    res[get<1>(V[i])] = 'A' + i;
  }
  return res;
}

map<char, char> make_rev(map<char, char> const &M)
{
  map<char, char> res;
  for (auto x : M)
  {
    res[x.second] = x.first;
  }
  return res;
}

string convert(string const &S, map<char, char> const &M)
{
  stringstream SS{};
  for (auto x : S)
  {
    SS << M.at(x);
  }
  return SS.str();
}

vector<string> split(string const &S, char c)
{
  vector<string> res;
  stringstream SS{};
  for (auto x : S)
  {
    if (x == c)
    {
      res.push_back(SS.str());
      SS.clear();
    }
    else
    {
      SS << x;
    }
  }
  return res;
}

string make_ans(string const &S)
{
  vector<int> cnt = count(S);
  assert(cnt[0] <= cnt[1] && cnt[1] == cnt[2]);
  vector<string> V = split(S, 'A');
  vector<int> now(3, 0);
  vector<vector<bool>> used(V.size());
  for (auto i = 0u; i < V.size(); i++)
  {
    used[i] = vector<bool>(V[i].size(), false);
  }
  // 1st step
  for (auto i = 0u; i < V.size(); i++)
  {
    if (V[i].size() % 2 == 1)
    {
      used[i][0] = true;
      now[V[i][0] - 'A']++;
    }
  }
  assert(now[0] == 0 && now[1] == now[2]);
  // 2nd step
  for (auto i = 1u; i < V.size() - 1; i++)
  {
    if (V[i].size() % 2 == 0)
    {
      used[i][0] = used[i][1] = true;
      now[V[i][0] - 'A']++;
      now[V[i][1] - 'A']++;
    }
  }
  assert(now[0] == 0 && now[1] == now[2]);
  // 3rd step
  if (now[1] < cnt[0])
  {
    for (auto i = 0u; i < V.size(); i++)
    {
      int num = V[i].size() - 1;
      while (num >= 1 && !used[i][num] && !used[i][num - 1])
      {
        used[i][num] = used[i][num - 1] = true;
        now[V[i][num] - 'A']++;
        now[V[i][num - 1] - 'A']++;
        num -= 2;
        if (now[1] == cnt[0])
        {
          break;
        }
      }
      if (now[1] == cnt[0])
      {
        break;
      }
    }
  }
  assert(now[0] == 0 && now[1] == now[2] && cnt[0] == now[1]);
  // make ans
  stringstream SS{};
  for (auto i = 0u; i < V.size(); i++)
  {
    for (auto j = 0u; j < V[i].size(); j++)
    {
      if (used[i][j])
      {
        SS << V[i][j];
      }
    }
    if (i < V.size() - 1)
    {
      SS << 'A';
    }
  }
  return SS.str();
}

string erase_C(string const &S)
{
  vector<int> cnt = count(S);
  stringstream SS{};
  for (auto i = 0u; i < S.size(); i++)
  {
    if (cnt[2] > cnt[1])
    {
      if (S[i] == 'C')
      {
        if (i - 1 >= 0 && i + 1 < S.size())
        {
          if ((S[i - 1] == 'A' && S[i + 1] == 'B') || (S[i - 1] == 'B' && S[i + 1] == 'A'))
          {
            cnt[2]--;
            continue;
          }
        }
        else
        {
          cnt[2]--;
          continue;
        }
      }
    }
    SS << S[i];
  }
  return SS.str();
}

string erase_AC(string const &S)
{
  vector<int> cnt = count(S);
  assert(cnt[0] <= cnt[1] && cnt[1] < cnt[2]);
  stringstream res{};
  for (auto i = 0u; i < S.size(); i++)
  {
    if (cnt[1] < cnt[2] && i < S.size() - 1 && S[i] == 'A' && S[i + 1] == 'C')
    {
      ++i;
      cnt[0]--;
      cnt[2]--;
    }
    else
    {
      res << S[i];
    }
  }
  return res.str();
}

int main()
{
  string S;
  cin >> S;
  S = reduce(S);
  map<char, char> M, R;
  M = make_map(S);
  R = make_rev(M);
  S = convert(S, M);
  vector<int> cnt = count(S);
  if (cnt[1] < cnt[2])
  {
    S = erase_C(S);
    cnt = count(S);
    if (cnt[1] < cnt[2])
    {
      S = erase_AC(S);
    }
  }
  string ans{make_ans(S)};
  ans = convert(ans, R);
  cout << ans << endl;
}<commit_msg>tried E.cpp to 'E'<commit_after>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 8/12/2019, 7:02:46 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 3000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

vector<int> count(string const &S)
{
  vector<int> cnt(3, 0);
  for (auto x : S)
  {
    cnt[x - 'A']++;
  }
  return cnt;
}

string reduce(string const &S)
{
  stringstream res{};
  char c{'x'};
  for (auto x : S)
  {
    if (x == c)
    {
      continue;
    }
    else
    {
      res << x;
      c = x;
    }
  }
  return res.str();
}

map<char, char> make_map(string const &S)
{
  vector<int> cnt = count(S);
  vector<tuple<int, char>> V;
  for (auto i = 0; i < 3; i++)
  {
    V.emplace_back(cnt[i], 'A' + i);
  }
  sort(V.begin(), V.end());
  map<char, char> res;
  for (auto i = 0; i < 3; i++)
  {
    res[get<1>(V[i])] = 'A' + i;
  }
  return res;
}

map<char, char> make_rev(map<char, char> const &M)
{
  map<char, char> res;
  for (auto x : M)
  {
    res[x.second] = x.first;
  }
  return res;
}

string convert(string const &S, map<char, char> const &M)
{
  stringstream SS{};
  for (auto x : S)
  {
    SS << M.at(x);
  }
  return SS.str();
}

vector<string> split(string const &S, char c)
{
  vector<string> res;
  stringstream SS{};
  for (auto x : S)
  {
    if (x == c)
    {
      res.push_back(SS.str());
      SS.clear();
    }
    else
    {
      SS << x;
    }
  }
  return res;
}

string make_ans(string const &S)
{
  vector<int> cnt = count(S);
  assert(cnt[0] <= cnt[1] && cnt[1] == cnt[2]);
  vector<string> V = split(S, 'A');
  vector<int> now(3, 0);
  vector<vector<bool>> used(V.size());
  for (auto i = 0u; i < V.size(); i++)
  {
    used[i] = vector<bool>(V[i].size(), false);
  }
  // 1st step
  for (auto i = 0u; i < V.size(); i++)
  {
    if (V[i].size() % 2 == 1)
    {
      used[i][0] = true;
      now[V[i][0] - 'A']++;
    }
  }
  assert(now[0] == 0 && now[1] == now[2]);
  // 2nd step
  for (auto i = 1u; i < V.size() - 1; i++)
  {
    if (V[i].size() % 2 == 0)
    {
      used[i][0] = used[i][1] = true;
      now[V[i][0] - 'A']++;
      now[V[i][1] - 'A']++;
    }
  }
  assert(now[0] == 0 && now[1] == now[2]);
  // 3rd step
  if (now[1] < cnt[0])
  {
    for (auto i = 0u; i < V.size(); i++)
    {
      int num = V[i].size() - 1;
      while (num >= 1 && !used[i][num] && !used[i][num - 1])
      {
        used[i][num] = used[i][num - 1] = true;
        now[V[i][num] - 'A']++;
        now[V[i][num - 1] - 'A']++;
        num -= 2;
        if (now[1] == cnt[0])
        {
          break;
        }
      }
      if (now[1] == cnt[0])
      {
        break;
      }
    }
  }
  assert(now[0] == 0 && now[1] == now[2] && cnt[0] == now[1]);
  // make ans
  stringstream SS{};
  for (auto i = 0u; i < V.size(); i++)
  {
    for (auto j = 0u; j < V[i].size(); j++)
    {
      if (used[i][j])
      {
        SS << V[i][j];
      }
    }
    if (i < V.size() - 1)
    {
      SS << 'A';
    }
  }
  return SS.str();
}

string erase_C(string const &S)
{
  vector<int> cnt = count(S);
  stringstream SS{};
  for (auto i = 0u; i < S.size(); i++)
  {
    if (cnt[2] > cnt[1])
    {
      if (S[i] == 'C')
      {
        if (i - 1 >= 0 && i + 1 < S.size())
        {
          if ((S[i - 1] == 'A' && S[i + 1] == 'B') || (S[i - 1] == 'B' && S[i + 1] == 'A'))
          {
            cnt[2]--;
            continue;
          }
        }
        else
        {
          cnt[2]--;
          continue;
        }
      }
    }
    SS << S[i];
  }
  return SS.str();
}

string erase_AC(string const &S)
{
  vector<int> cnt = count(S);
  assert(cnt[0] <= cnt[1] && cnt[1] < cnt[2]);
  stringstream res{};
  for (auto i = 0u; i < S.size(); i++)
  {
    if (cnt[1] < cnt[2] && i < S.size() - 1 && S[i] == 'A' && S[i + 1] == 'C')
    {
      ++i;
      cnt[0]--;
      cnt[2]--;
    }
    else
    {
      res << S[i];
    }
  }
  return res.str();
}

int main()
{
  string S;
  cin >> S;
  S = reduce(S);
  map<char, char> M, R;
  M = make_map(S);
  R = make_rev(M);
  S = convert(S, M);
#if DEBUG == 1
  cerr << "S = " << S << endl;
#endif
  vector<int> cnt = count(S);
  if (cnt[1] < cnt[2])
  {
    S = erase_C(S);
#if DEBUG == 1
    cerr << "S = " << S << endl;
#endif
    cnt = count(S);
    if (cnt[1] < cnt[2])
    {
      S = erase_AC(S);
#if DEBUG == 1
      cerr << "S = " << S << endl;
#endif
    }
  }
  string ans{make_ans(S)};
  ans = convert(ans, R);
  cout << ans << endl;
}<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 11/18/2019, 8:58:07 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
// ----- boost -----
#include <boost/rational.hpp>
// ----- using directives and manipulations -----
using boost::rational;
using namespace std;
using ll = long long;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{3000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

void add_edge(map<int, int> &m, int h, int d)
{
  if (m.find(h) == m.end())
  {
    m[h] = d;
  }
  else
  {
    ch_min(m[h], d);
  }
}

void calc_high(vector<int> const &A, vector<map<int, int>> &M, int i, int h, int d)
{
  add_edge(M[i + 1], A[i + 1] - (A[i] - h), d);
  add_edge(M[i + 1], h, d + 1);
  add_edge(M[i + 1], 0, d + 2);
}

void calc_low(vector<int> const &A, vector<map<int, int>> &M, int i, int h, int d)
{
  if (h <= A[i + 1])
  {
    add_edge(M[i + 1], h, d);
  }
  add_edge(M[i + 1], max(0, A[i + 1] - (A[i] - h)), d + 1);
  add_edge(M[i + 1], 0, d + 2);
}

void eliminate(map<int, int> &m)
{
  int now{m[0]};
  auto k{make_unique<map<int, int>>()};
  for (auto x : m)
  {
    if (x.second == now)
    {
      k->insert(x);
      --now;
    }
  }
  swap(m, *k);
}

void calc(vector<int> const &A, vector<map<int, int>> &M, int i, pair<int, int> const &x)
{
  int h{x.first};
  int d{x.second};
  if (A[i] <= A[i + 1])
  {
    calc_high(A, M, i, h, d);
  }
  else
  {
    calc_low(A, M, i, h, d);
  }
  eliminate(M[i + 1]);
#if DEBUG == 1
  for (auto const &x : M[i + 1])
  {
    cerr << "M[" << i + 1 << "][" << x.first << "] = " << x.second << endl;
  }
#endif
}

int main()
{
  int N;
  cin >> N;
  vector<int> A(N + 2, 0);
  for (auto i = 1; i <= N; i++)
  {
    cin >> A[i];
  }
  vector<map<int, int>> M(N + 2);
  M[0][0] = 0;
  for (auto i = 0; i <= N; i++)
  {
    for (auto const &x : M[i])
    {
      calc(A, M, i, x);
    }
  }
  cout << M[N + 1].end()->second << endl;
}
<commit_msg>tried E.cpp to 'E'<commit_after>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 11/18/2019, 8:58:07 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
// ----- boost -----
#include <boost/rational.hpp>
// ----- using directives and manipulations -----
using boost::rational;
using namespace std;
using ll = long long;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{3000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

void add_edge(map<int, int> &m, int h, int d)
{
  if (m.find(h) == m.end())
  {
    m[h] = d;
  }
  else
  {
    ch_min(m[h], d);
  }
}

void calc_high(vector<int> const &A, vector<map<int, int>> &M, int i, int h, int d)
{
  add_edge(M[i + 1], A[i + 1] - (A[i] - h), d);
  add_edge(M[i + 1], h, d + 1);
  add_edge(M[i + 1], 0, d + 2);
}

void calc_low(vector<int> const &A, vector<map<int, int>> &M, int i, int h, int d)
{
  if (h <= A[i + 1])
  {
    add_edge(M[i + 1], h, d);
  }
  add_edge(M[i + 1], max(0, A[i + 1] - (A[i] - h)), d + 1);
  add_edge(M[i + 1], 0, d + 2);
}

void eliminate(map<int, int> &m)
{
  int now{m[0]};
  auto k{make_unique<map<int, int>>()};
  for (auto const &x : m)
  {
    if (x.second == now)
    {
      k->insert(x);
      --now;
    }
  }
  swap(m, *k);
}

void calc(vector<int> const &A, vector<map<int, int>> &M, int i, pair<int, int> const &x)
{
  int h{x.first};
  int d{x.second};
  if (A[i] <= A[i + 1])
  {
    calc_high(A, M, i, h, d);
  }
  else
  {
    calc_low(A, M, i, h, d);
  }
#if DEBUG == 1
  for (auto const &x : M[i + 1])
  {
    cerr << "M[" << i + 1 << "][" << x.first << "] = " << x.second << endl;
  }
#endif
  eliminate(M[i + 1]);
#if DEBUG == 1
  for (auto const &x : M[i + 1])
  {
    cerr << "M[" << i + 1 << "][" << x.first << "] = " << x.second << endl;
  }
#endif
}

int main()
{
  int N;
  cin >> N;
  vector<int> A(N + 2, 0);
  for (auto i = 1; i <= N; i++)
  {
    cin >> A[i];
  }
  vector<map<int, int>> M(N + 2);
  M[0][0] = 0;
  for (auto i = 0; i <= N; i++)
  {
    for (auto const &x : M[i])
    {
      calc(A, M, i, x);
    }
  }
  cout << M[N + 1].end()->second << endl;
}
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 6/8/2020, 2:28:47 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- main() -----

int main()
{
  ll N, K;
  cin >> N >> K;
  vector<ll> A(N);
  for (auto i{0}; i < N; ++i)
  {
    cin >> A[i];
    A[i]--;
  }
  vector<ll> sum(N + 1, 0);
  for (auto i{0}; i < N; ++i)
  {
    sum[i + 1] = A[i] + sum[i];
    sum[i + 1] %= K;
  }
  map<ll, ll> M;
  for (auto e : sum)
  {
    if (M.find(e) == M.end())
    {
      M[e] = 1;
    }
    else
    {
      M[e]++;
    }
  }
  ll ans{0};
  for (auto const &e : M)
  {
    auto c{e.second};
    ans += c * (c - 1) / 2;
  }
  cout << ans << endl;
}
<commit_msg>tried E.cpp to 'E'<commit_after>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 6/8/2020, 2:28:47 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- main() -----

int main()
{
  ll N, K;
  cin >> N >> K;
  vector<ll> A(N);
  for (auto i{0}; i < N; ++i)
  {
    cin >> A[i];
    A[i]--;
  }
  vector<ll> sum(N + 1, 0);
  for (auto i{0}; i < N; ++i)
  {
    sum[i + 1] = A[i] + sum[i];
  }
  map<ll, ll> M;
  ll ans{0};
  for (auto i{0}; i < N + 1; ++i)
  {
    ans += M[sum[i]];
    if (i - K >= 0)
    {
      M[sum[i - K]]--;
    }
  }
  cout << ans << endl;
}
<|endoftext|>